/**
 @file sys_tmg_mac.c

 @date 2023-02-13

 @version v0.1

*/

/****************************************************************************
 *
* Header Files
*
****************************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_interrupt.h"
#include "ctc_warmboot.h"
#include "sys_usw_common.h"
#include "sys_usw_chip.h"
#include "sys_usw_peri.h"
#include "sys_usw_stats_api.h"
#include "sys_usw_dmps.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_port.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_mcu.h"
#include "sys_usw_flexe.h"
#include "sys_usw_register.h"
#include "sys_usw_phy.h"
#include "sys_usw_datapath.h"
#include "sys_usw_dmps_drv_def.h"
#include "sys_tmg_datapath.h"
#include "sys_tmg_mac.h"
#include "sys_tmg_serdes.h"
#include "drv_api.h"
#include "usw/include/drv_common.h"
#include "sys_usw_register.h"
#include "../sys_usw_dmps_api.h"
#include "../sys_usw_dmps_shared_api.h"
#include "usw/include/sys/sys_usw_serdes_api.h"


/****************************************************************************
 *
* Global and Declaration
*
*****************************************************************************/
extern sal_file_t g_tm_dump_fp;
extern const uint8 g_dmps_dbg_sw;
extern uint8 g_print_tbl;

#ifdef DRV_IOW_FIELD
#undef DRV_IOW_FIELD
#define DRV_IOW_FIELD(lchip, memid, fieldid, value, ptr) \
     do\
     {\
         int retv = 0;\
         char   fld_str[64] = {0};\
         retv = drv_set_field(lchip, memid, fieldid, ptr, value);\
         if (retv < 0)\
         {\
             return(retv); \
         }\
         drv_usw_get_field_string_by_id(lchip, memid, fieldid, fld_str);\
         if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw)) \
         {\
             sal_fprintf(g_tm_dump_fp, "write %s 0 %s 0x%x\n", \
                 TABLE_NAME(lchip, memid), fld_str, *value); \
             sal_fflush(g_tm_dump_fp);\
         }\
     }\
     while(0)
#endif

/* DRV_IOW_FIELD extender, for index Not Zero */
#define DRV_IOW_FIELD_NZ(lchip, memid, fieldid, value, ptr, inst, index) \
     do\
     {\
         int retv = 0;\
         char   fld_str[64] = {0};\
         retv = drv_set_field(lchip, memid, fieldid, ptr, value);\
         if (retv < 0)\
         {\
             return(retv); \
         }\
         drv_usw_get_field_string_by_id(lchip, memid, fieldid, fld_str);\
         if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw)) \
         {\
             sal_fprintf(g_tm_dump_fp, "//write chip 0 tbl-reg  %s.%d  %d  field %s %d\n", \
                 TABLE_NAME(lchip, memid), inst, index, fld_str, *value); \
             sal_fflush(g_tm_dump_fp);\
         }\
     }\
     while(0)

#define DRV_IOW_FIELD_NZ_1(lchip, memid, fieldid, value, ptr, inst, index) \
     do\
     {\
         int retv = 0;\
         char   fld_str[64] = {0};\
         retv = drv_set_field(lchip, memid, fieldid, ptr, value);\
         if (retv < 0)\
         {\
             return(retv); \
         }\
         drv_usw_get_field_string_by_id(lchip, memid, fieldid, fld_str);\
         if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw)) \
         {\
             sal_printf("write %s  %d  %s     0x%x inst %d\n", \
                 TABLE_NAME(lchip, memid), index, fld_str, *value, inst); \
         }\
     }\
     while(0)

#define DP_DEBUG_FUNCTION_CALLED_PRINT() \
            do \
            { \
                if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw)) \
                {\
                    sal_fprintf(g_tm_dump_fp, "//------ %s enter ----------------\n", __func__); \
                }\
            } \
            while(0)
        
#define DP_DEBUG_FUNCTION_RETURN_PRINT() \
            do \
            { \
                if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw)) \
                {\
                    sal_fprintf(g_tm_dump_fp, "//------ %s return ----------------\n", __func__); \
                }\
            } \
            while(0)


#define DMPS_DUMP_PRINT(...)  do { \
        if(g_dmps_dbg_sw && g_tm_dump_fp) {\
            sal_fprintf(g_tm_dump_fp, __VA_ARGS__);\
            sal_fflush(g_tm_dump_fp); }\
        sal_printf(__VA_ARGS__);\
    } while(0)


extern void 
_sys_usw_mac_show_cl73_ability(uint32 value);
extern int32
_sys_usw_dmps_get_fec(uint8 lchip, uint16 lport, uint32* p_value);
extern int32
_sys_tmg_datapath_dynamic_switch(uint8 lchip, sys_dmps_ds_list_t* target, uint8 is_switch_serdes);
extern int32
_sys_tmg_datapath_dynamic_switch_check(uint8 lchip, sys_dmps_ds_list_t* target);
extern int32
_sys_tmg_datapath_get_serdes_chan_by_lport(uint8 lchip, uint16 dport, uint16* p_chan, uint16* p_logic_serdes);
extern int32
_sys_tmg_datapath_get_lport_chan_by_serdes(uint8 lchip, uint16 logic_serdes, uint16* p_chan, uint16* p_dport);
extern int32
_sys_tmg_datapath_get_free_chan(uint8 lchip, uint16 dport, uint8 free_num, uint16* free_chan, uint8* free_sub_chan, uint8* free_mac_client, uint8 dir);
extern int32
_sys_tmg_datapath_check(uint8 lchip, uint8 dp_id, uint8 dp_txqm, sys_dmps_change_chan_info_t* info, uint8 dir, uint8 check_bw);
extern int32
_sys_tmg_datapath_xpipe_resource_alloc(uint8 lchip, uint16 dport, uint8 chan_num, uint16* chan_list, uint8 dir);
extern int32
_sys_tmg_datapath_resource_alloc_chan(uint8 lchip, uint16 chan_id, uint8 enable, uint8 dir, uint8 is_xpipe);

extern int32
sys_tmg_serdes_set_hss_tx_rst(uint8 lchip, uint16 psd, uint32 rst);

extern int32
sys_tmg_serdes_set_trx_dataout_sel(uint8 lchip, uint8 hss_id, uint8 psd_num, uint16 psd[], uint8 if_mode);

extern int32
sys_tmg_serdes_set_trx_bit_reverse(uint8 lchip, uint8 hss_id, uint8 psd_num, uint16 psd[], uint32 value);

extern int32
sys_tmg_serdes_set_hss_clktree_cfg(uint8 lchip, uint8 hss_id, uint8 psd_num, uint16 psd[], uint8 if_mode);

//extern STATIC int32
//_sys_tsingma_peri_get_chip_sensor(uint8 lchip, ctc_chip_sensor_type_t type, uint32* p_value);
int32
_sys_tmg_mac_set_xpipe_db(uint8 lchip, uint16 lport, uint32 value, uint8 dir);
int32
_sys_tmg_mac_set_mac_config(uint8 lchip, uint16 mac_id);
int32 
_sys_tmg_mac_set_link_intr(uint8 lchip, uint16 dport, uint8 enable);
int32 
_sys_tmg_mac_get_link_intr(uint8 lchip, uint16 dport, uint32* p_enable);
int32 
_sys_tmg_mac_get_fec_cnt(uint8 lchip, uint16 dport, void* p_value);
int32
sys_tmg_mac_isr_event_dispatch(uint8 lchip, uint32 intr, void* p_data);
int32
_sys_tmg_mac_set_cl73_ability(uint8 lchip, uint16 dport, uint32 ability);
int32
_sys_tmg_mac_get_pcs_code_err(uint8 lchip, uint16 dport, uint32* p_value);
int32
_sys_tmg_mac_set_pcs_rst(uint8 lchip, uint16 dport, uint8 dir, uint8 reset);
int32
_sys_tmg_mac_set_port_serdes_tx_en(uint8 lchip, uint16 lport, uint8 en);
int32
_sys_tmg_mac_cl73_write_field(uint8 lchip, uint16 serdes_id, _sys_tmg_cl73_field_t* p_field_info, uint32 data);
int32
_sys_tmg_unmask_link_intr(uint8 lchip);
int32 
_sys_tmg_cpumac_init_m2c(uint8 lchip);
int32
_sys_tmg_mac_cl73_init(uint8 lchip);
int32
_sys_tmg_mac_set_cl73_ability_hw(uint8 lchip, uint16 dport, sys_dmps_an_ability_t *p_ability);
int32
_sys_tmg_mac_get_loopback_mode(uint8 lchip, void* p_psd, uint32* p_lpbk_mode);
int32
_sys_tmg_mac_cl73_reg_acc_init(uint8 lchip, uint16 serdes_id, uint32 en);
int32
_sys_tmg_mac_init_cl73_ability(uint8 lchip, uint16 psd);
int32
_sys_tmg_mac_get_cl37_en(uint8 lchip, uint16 lport, uint32* p_value);
int32
_sys_tmg_mac_get_cl73_en(uint8 lchip, uint16 lport, uint32* p_en);
int32
_sys_tmg_mac_get_cl37_mode(uint8 lchip, uint16 lport, uint32* p_mode);
int32
_sys_tmg_mac_get_cl37_an_remote_status(uint8 lchip, uint16 lport, uint32 auto_neg_mode, uint32* p_speed, uint32* p_link);

uint16 _sys_tmg_mac_xpipe_map_lower_speed(uint8 lchip, uint16 src_speed);

void sys_usw_mac_link_log_record(uint8 lchip, uint16 lport, uint8 type, uint16 val);
extern int32 sys_tmg_mcu_send_link_up_intr(uint8 lchip, uint16 dport);
extern int32 sys_tmg_mcu_get_anlt_state(uint8 lchip, uint16 dport, uint32* p_state);
extern int32 sys_usw_dmps_anlt_sm_send_link_down_msg(uint8 lchip, uint16 dport, uint8 pcs_status);
extern int32 sys_usw_port_api_mac_isr_dispatch(uint8 lchip, uint32 intr, void* p_data);

struct cl73_ability_ctc_sys_map_tbl_s
{
    uint32  ctc_ability;
    uint32  sys_ability;
    uint32* p_ability;
};
typedef struct cl73_ability_ctc_sys_map_tbl_s cl73_ability_ctc_sys_map_tbl_t;

#define SYS_TMG_MAC_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

/****************************************************************************
 *
* Function
*
*****************************************************************************/
/* get dynamic switch dport */
int32
_sys_tmg_mac_get_dynamic_switch_list(uint8 lchip, uint16 physical_serdes, sys_dmps_ds_list_t* target)
{    
    uint8  if_mode        = 0;
    uint8  is_dyn         = 0;
    uint8  port_num       = 0;
    uint8  dst_serdes_num = 0;
    uint8  src_serdes_num = 0;
    uint8  serdes_num     = 0;
    uint8  dport_num      = 0;
    uint8  port_type      = 0;
    uint8  fec_type       = 0;
    uint8  xpipe_en       = 0;
    uint16 dport          = 0;
    uint16 chan_id        = 0;
    uint16 logical_serdes = 0;
    uint16 end_serdes     = 0;
    uint16 start_serdes   = 0;
    uint16 speed          = 0;
    uint32 support_speed  = 0;
    ctc_chip_serdes_mode_t  src_mode = 0;
    ctc_chip_serdes_mode_t  dst_mode = target->dst_mode;
    sys_dmps_db_upt_info_t port_info = {0};
    uint16 dport_list[DMPS_MAX_NUM_PER_MODULE] = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_PHYSIC_SERDES, physical_serdes);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT,        dport);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES, logical_serdes);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE,  if_mode);

    /* get source mode */
    if (!sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, dport))
    {
        src_mode = CTC_CHIP_SERDES_NONE_MODE;
    }
    else
    {
        src_mode = if_mode;
    }

    SYS_DMPS_GET_SERDES_NUM_BY_MODE(src_mode, src_serdes_num);
    SYS_DMPS_GET_SERDES_NUM_BY_MODE(dst_mode, dst_serdes_num);
    fec_type = SYS_DMPS_IS_PAM4_MODE(dst_mode) ? SYS_DMPS_FEC_TYPE_RS544 : SYS_DMPS_FEC_TYPE_NONE;
//sal_printf(" logical serdes list: ");
    /* get logical serdes list */
    if ((CTC_CHIP_SERDES_NONE_MODE == src_mode) && (CTC_CHIP_SERDES_NONE_MODE == dst_mode))
    {
        target->lsd_num = 0;
    }
    else
    {
        serdes_num      = (src_serdes_num > dst_serdes_num) ? src_serdes_num : dst_serdes_num;
        logical_serdes  = logical_serdes - logical_serdes % serdes_num;
        target->lsd_num = 0;
        while (target->lsd_num < serdes_num)
        {
            target->lsd_list[target->lsd_num] = logical_serdes + target->lsd_num;
//sal_printf("%d ", target->lsd_list[target->lsd_num]);

            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES, target->lsd_list[target->lsd_num]);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PSD_IS_DYN);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PSD_SUPPORT_SPEED);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PSD_IS_DYN, is_dyn);
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PSD_SUPPORT_SPEED, support_speed);
            /* check whether serdes supports dynamic switch */
            if (SYS_SERDES_DYN_FORBID_ALL == is_dyn)
            {
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Logic serdes %u fobid dynamic switch!\n", target->lsd_list[target->lsd_num]);
                return CTC_E_NOT_SUPPORT;
            }
            speed          = sys_usw_dmps_get_speed_from_serdes_info(dst_mode, fec_type, CTC_CHIP_SERDES_OCS_MODE_NONE);
            if (!((1 << speed) & support_speed))
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Serdes cannot support this speed!  \n");
                return CTC_E_INVALID_CONFIG;
            }
            target->lsd_num++;
        }
    }
//sal_printf("\n");
    start_serdes = logical_serdes;
    end_serdes   = logical_serdes + target->lsd_num;
//sal_printf(" dport list: ");
    /* get dport list */
    while (logical_serdes < end_serdes)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES, logical_serdes);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_XPIPE_EN);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT,        dport);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE,  if_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,     port_type);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_XPIPE_EN, xpipe_en);

        if (xpipe_en)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Port % d with xpipe enable cannot support dynamic switch!\n", dport);
            return CTC_E_NOT_SUPPORT;
        }

        if (!sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, dport))
        {
            logical_serdes++;
            continue;
        }
        else
        {
            SYS_DMPS_GET_SERDES_NUM_BY_MODE(if_mode, serdes_num);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, logical_serdes, DMPS_DB_TYPE_PORT, &port_num, dport_list));
            for (dport_num = 0; dport_num < port_num; dport_num ++)
            {
                target->src_dport_list[target->src_dport_num] = dport_list[dport_num];

                /* check validity of network port */
                if (!SYS_TMG_IS_MODE_VALID(target->dst_mode))
                {
                    sal_printf("NW dport %u, port_type %u, dst_mode %u\n", dport, port_type, target->dst_mode);
                    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Dport %u donnot support the mode!\n", dport);
                    return CTC_E_NOT_SUPPORT;
                }
                
//sal_printf("%d ", target->src_dport_list[target->src_dport_num]);
                target->src_dport_num++; 
            }
            
            logical_serdes += serdes_num;
        }
    }
//sal_printf("\n");
//sal_printf(" chan list: ");
    /* get chan list */
    for(dport_num = 0; dport_num < target->src_dport_num; dport_num++)
    {
        dport = target->src_dport_list[dport_num];
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_dport_relative_id(lchip, dport, DMPS_DB_TYPE_CHAN, &chan_id));
        target->chan_info.src_chan_list[target->chan_info.src_chan_num] = chan_id;
        target->chan_info.src_chan_num++;
//sal_printf("%d ", chan_id);
    }
//sal_printf("\n");
    if (CTC_CHIP_SERDES_NONE_MODE == dst_mode)
    {
        return CTC_E_NONE;
    }
//sal_printf(" dst dport and chan list: ");
    /* get dst dport and chan list */
    logical_serdes = start_serdes;
    while (logical_serdes < end_serdes)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_get_lport_chan_by_serdes(lchip, logical_serdes, &chan_id, &dport));
        if (!sys_usw_dmps_db_is_usable_id(lchip, DMPS_DB_TYPE_PORT, dport))
        {
            return CTC_E_INVALID_PARAM;
        }

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,    port_type);

        SYS_TMG_GET_PORT_NUM_BY_MODE(dst_mode, port_num);
        for (dport_num = 0; dport_num < port_num; dport_num ++)
        {
            target->dst_dport_list[target->dst_dport_num] = dport;
            target->dst_dport_num++;
            target->chan_info.dst_chan_list[target->chan_info.dst_chan_num]   = chan_id;
            target->chan_info.dst_chan_num++;
        
            /* check validity of NW / CPUMAC port */
            if(!SYS_TMG_IS_MODE_VALID(target->dst_mode))
            {
                SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Dport %u donnot support the mode!\n", dport);
                return CTC_E_NOT_SUPPORT;
            }
            
//sal_printf(" dport %d chan %d ", dport, chan_id);
            
            dport++;
            chan_id++;
        }

        logical_serdes += dst_serdes_num;
    }
//sal_printf("\n");

    return CTC_E_NONE;
}

///TODO:
/* Dynamic Switch */
int32
_sys_tmg_mac_dynamic_switch_get_list(uint8 lchip, uint16 lport, void* p_mode, void* p_ds_list)
{ 
    uint8  port_type = 0;
    uint16 psd       = 0;
    uint16 lsd       = 0;
    uint8  ovclk     = CTC_CHIP_SERDES_OCS_MODE_NONE;
    uint16 dport     = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    ctc_chip_serdes_mode_t dst_mode  = CTC_CHIP_SERDES_NONE_MODE;
    sys_dmps_db_upt_info_t port_info = {0};
    ctc_port_if_mode_t*    if_mode   = (ctc_port_if_mode_t*)p_mode;
    sys_dmps_ds_list_t*    p_list    = (sys_dmps_ds_list_t*)p_ds_list;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    
    SYS_CONDITION_RETURN(!sys_usw_dmps_db_is_usable_id(lchip, DMPS_DB_TYPE_PORT, dport), CTC_E_INVALID_PARAM);

    SYS_DMPS_GET_SERDES_MODE_BY_IFMODE(((sys_port_speed_t) if_mode->speed), if_mode->interface_type, dst_mode);

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,    0);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, 0);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN, 0);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,    port_type);

    if((SYS_USW_IS_CPUMAC_PORT(port_type)) && (SYS_DMPS_IS_PAM4_MODE(dst_mode)))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% CPUMAC connot support the mode \n");
        return CTC_E_PARAM_CONFLICT;
    }

    if (CTC_CHIP_MAX_SERDES_MODE == dst_mode)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Interface speed and type not match \n");
        return CTC_E_PARAM_CONFLICT;
    }

    if(CTC_E_NONE != sys_usw_dmps_db_get_dport_relative_id(lchip, dport, DMPS_DB_TYPE_PSD, &psd))
    {
        /* if port type of the dport is NONE */
        CTC_ERROR_RETURN(_sys_tmg_datapath_get_serdes_chan_by_lport(lchip, lport, NULL, &lsd));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, lsd,
            DMPS_DB_TYPE_PSD, NULL, &psd));
    }

    /* 1. get logical serdes, dport, chan list with dynamic switch */
    p_list->ovclk    = ovclk;
    p_list->dst_mode = dst_mode;
    SYS_DMPS_GET_PORT_SPEED(dst_mode, p_list->chan_info.dst_speed_mode);
    CTC_ERROR_RETURN(_sys_tmg_mac_get_dynamic_switch_list(lchip, psd, p_list));

    /* 2. check param */
    CTC_ERROR_RETURN(_sys_tmg_datapath_dynamic_switch_check(lchip, p_list));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_dynamic_switch_set_config(uint8 lchip, void* p_ds_list, uint32 option_bmp)
{
    uint8 idx = 0;
    uint16 dport = 0;
    uint8 is_switch_serdes = CTC_IS_BIT_SET(option_bmp, DMPS_DS_OPTION_SERDES_SWITCH);
    sys_dmps_ds_list_t* p_list = (sys_dmps_ds_list_t*)p_ds_list;

    /* switch database and config register */
    CTC_ERROR_RETURN(_sys_tmg_datapath_dynamic_switch(lchip, p_list, is_switch_serdes));

    SYS_CONDITION_RETURN(p_list->dst_dport_num > SYS_DATAPATH_DS_MAX_PORT_NUM, CTC_E_INVALID_PARAM);

    if (CTC_IS_BIT_SET(option_bmp, DMPS_DS_OPTION_CLEAR_CL73))
    {
        for(idx = 0; idx < p_list->dst_dport_num; idx++)
        {
            dport = p_list->dst_dport_list[idx];
            ///TODO: get cl73 en
            CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_switch_off_msg(lchip, dport));
            ///TODO: set cl73 db
        }
    }

    return CTC_E_NONE;
}

///TODO:
uint8
_sys_tmg_mac_is_power_up(uint8 lchip, uint8 txqm_id)
{
    uint16 start_psd    = 0;
    uint16 end_psd      = 0;
    uint16 psd          = 0;
    uint32 serdes_speed = 0;

    if(txqm_id == SYS_TMG_CPUMAC_TXQM_ID)
    {
        start_psd = SYS_TMG_MAX_SERDES_NUM_NW;   
        end_psd   = start_psd + SYS_TMG_CPUMAC_SERDSES_NUM;    
    }
    else
    {
        start_psd = SYS_TMG_PCS_LANE_NUM * txqm_id;
        end_psd   = start_psd + SYS_TMG_PCS_LANE_NUM;               
    }

    for (psd = start_psd; psd < end_psd; psd++)
    {
        (void) sys_usw_dmps_db_get_serdes_speed(lchip, psd, &serdes_speed);
        if (serdes_speed)
        {
            return TRUE;
        }
    }

    return FALSE;
}

///TODO:
int32 
_sys_tmg_mac_set_nw_group_enable(uint8 lchip, uint8 txqm_id, uint8 enable)
{
   #if 0
    uint32 tbl_id   = 0;
    uint32 index    = 0;
    uint32 cmd      = 0;
    uint32 value    = 0;
    uint8  group_in_txqm = 0;
    uint8  mac_grp       = 0;

    CtcPcsCtlCfg_m    pcs_reset;
    CtcPcsCtlCfg_m    pcs_enclk;
    CtcMacCtlReset_m    mac_reset;
    CtcMacCtlEnClk_m    mac_enclk;
    CtcHsCtlReset_m     hs_reset;
    CtcHsCtlEnClk_m     hs_enclk;

    if(enable)
    {
        value   = 1;
        tbl_id  = CtcHsCtlEnClk_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);       
        index  = DRV_INS(txqm_id, 0);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hs_enclk));
        
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlEnClk_enClkMcu_f  , &value, &hs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlEnClk_enClkMcuIntf_f  , &value, &hs_enclk, txqm_id, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hs_enclk));

        value   = 0;
        tbl_id  = CtcHsCtlReset_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hs_reset));
        
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlReset_resetCoreCtcMac_f  , &value, &hs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlReset_resetCoreCtcPcs_f  , &value, &hs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlReset_resetCoreMcu_f     , &value, &hs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlReset_resetCoreMcuIntf_f , &value, &hs_reset, txqm_id, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hs_reset));

        value   = 1;
        tbl_id  = CtcMacCtlEnClk_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_enclk));
        
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkQuadSgmac0_f, &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkQuadSgmac1_f, &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac0_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac1_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac2_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac3_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac4_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac5_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac6_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac7_f    , &value, &mac_enclk, txqm_id, 0);        
        
        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_enclk));    

        tbl_id  = CtcPcsCtlCfg_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &pcs_enclk));
        
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs0_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs1_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs2_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs3_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs4_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs5_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs6_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs7_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs0_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs1_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs2_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs3_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs4_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs5_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs6_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs7_f  , &value, &pcs_enclk, txqm_id, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &pcs_enclk));

        value  = 0;
        tbl_id = CtcPcsCtlCfg_t;
        cmd    = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &pcs_reset));

        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreCgPcs0_f,                &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreCgPcs1_f,                &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapper0_f,    &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapper1_f,    &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapperReg0_f, &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapperReg1_f, &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii0_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii1_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii2_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii3_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii4_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii5_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii6_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii7_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs0_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs1_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs2_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs3_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs4_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs5_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs6_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs7_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedFecReg0_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedFecReg1_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedMiiReg0_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedMiiReg1_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedPcsReg0_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedPcsReg1_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs0_f,               &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs1_f,               &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs2_f,               &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs3_f,               &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetSharedFec0_f,                &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetSharedFec1_f,                &value, &pcs_reset, txqm_id, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &pcs_reset));
        
        tbl_id = CtcMacCtlReset_t;
        cmd    = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_reset));

        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreQuadSgmac0_f    , &value, &mac_reset, txqm_id, 0);       
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreQuadSgmac1_f    , &value, &mac_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreQuadSgmacReg0_f , &value, &mac_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreQuadSgmacReg1_f , &value, &mac_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreTsRcQuad_f      , &value, &mac_reset, txqm_id, 0);       

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_reset));

        for(group_in_txqm = 0; group_in_txqm < SYS_TMG_HSS_NUM_PER_TXQM; group_in_txqm++)
        {
            mac_grp = group_in_txqm + SYS_TMG_HSS_NUM_PER_TXQM * txqm_id;
            index = DRV_INS(mac_grp, 0);
            cmd = DRV_IOW(QuadSgmacInit_t, QuadSgmacInit_init_f);
            value = 0;
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));

            value = 1;
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));
#ifdef EMULATION_ENV
            sal_task_sleep(5000);
#else
            sal_task_sleep(1);
#endif     
            cmd = DRV_IOR(QuadSgmacInitDone_t, QuadSgmacInitDone_initDone_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));
            if(!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QuadSgmacInitDone.initDone] Feature not initialized \n");
                return CTC_E_NOT_INIT;
            }
        }
    }
    else
    {
        value = 1;
    
        tbl_id = CtcPcsCtlCfg_t;
        index  = DRV_INS(txqm_id, 0);
        cmd    = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &pcs_reset));

        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreCgPcs0_f,                &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreCgPcs1_f,                &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapper0_f,    &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapper1_f,    &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapperReg0_f, &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapperReg1_f, &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii0_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii1_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii2_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii3_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii4_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii5_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii6_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii7_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs0_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs1_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs2_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs3_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs4_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs5_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs6_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs7_f,                  &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedFecReg0_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedFecReg1_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedMiiReg0_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedMiiReg1_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedPcsReg0_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedPcsReg1_f,         &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs0_f,               &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs1_f,               &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs2_f,               &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs3_f,               &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetSharedFec0_f,                &value, &pcs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetSharedFec1_f,                &value, &pcs_reset, txqm_id, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &pcs_reset));
        
        tbl_id = CtcMacCtlReset_t;
        cmd    = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_reset));

        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreQuadSgmac0_f    , &value, &mac_reset, txqm_id, 0);       
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreQuadSgmac1_f    , &value, &mac_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreQuadSgmacReg0_f , &value, &mac_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreQuadSgmacReg1_f , &value, &mac_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMacCtlReset_resetCoreTsRcQuad_f      , &value, &mac_reset, txqm_id, 0);       

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_reset));

        value   = 0;
        tbl_id  = CtcPcsCtlCfg_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &pcs_enclk));
        
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs0_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs1_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs2_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs3_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs4_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs5_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs6_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkSgmiiPcs7_f, &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs0_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs1_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs2_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs3_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs4_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs5_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs6_f  , &value, &pcs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcPcsCtlCfg_enClkXfiPcs7_f  , &value, &pcs_enclk, txqm_id, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &pcs_enclk));

        tbl_id  = CtcMacCtlEnClk_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_enclk));
        
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkQuadSgmac0_f, &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkQuadSgmac1_f, &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac0_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac1_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac2_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac3_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac4_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac5_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac6_f    , &value, &mac_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcMacCtlEnClk_enClkSgmac7_f    , &value, &mac_enclk, txqm_id, 0);        
        
        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_enclk));    

        value   = 1;
        tbl_id  = CtcHsCtlReset_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hs_reset));
        
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlReset_resetCoreCtcMac_f  , &value, &hs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlReset_resetCoreCtcPcs_f  , &value, &hs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlReset_resetCoreMcu_f     , &value, &hs_reset, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlReset_resetCoreMcuIntf_f , &value, &hs_reset, txqm_id, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hs_reset));

        value   = 0;
        tbl_id  = CtcHsCtlEnClk_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hs_enclk));
        
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlEnClk_enClkMcu_f  , &value, &hs_enclk, txqm_id, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id,CtcHsCtlEnClk_enClkMcuIntf_f  , &value, &hs_enclk, txqm_id, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hs_enclk));
       
    }
    #endif
    return CTC_E_NONE;    
}

int32 
_sys_tmg_mac_set_cpumac_group_enable(uint8 lchip, uint8 enable)
{
    uint32 tbl_id   = 0;
    uint32 index    = 0;
    uint32 cmd      = 0;
    uint32 value    = 0;

    CtcMiscCtlClkEn_m   misc_enclk;
    CtcMiscCtlReset_m   misc_reset;
    CpuMacCtlEnClk_m    cpumac_enclk;
    CpuMacCtlResetCtl_m cpumac_reset;

    if(enable)
    {
        value   = 1;
        tbl_id  = CtcMiscCtlClkEn_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &misc_enclk));

        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlClkEn_enClkMcu_f     , &value, &misc_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlClkEn_enClkMcuIntf_f , &value, &misc_enclk, 0, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &misc_enclk));

        value = 0;      
        tbl_id  = CtcMiscCtlReset_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &misc_reset));

        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlReset_resetCoreCpuMac_f , &value, &misc_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlReset_resetMcu_f        , &value, &misc_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlReset_resetCoreMcuIntf_f, &value, &misc_reset, 0, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &misc_reset));

        value   = 1;
        tbl_id  = CpuMacCtlEnClk_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_enclk));

        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkQuadSgmac_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmac0_f   , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmac1_f   , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmac2_f   , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmac3_f   , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmiiPcs0_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmiiPcs1_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmiiPcs2_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmiiPcs3_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkXfiPcs0_f  , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkXfiPcs1_f  , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkXfiPcs2_f  , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkXfiPcs3_f  , &value, &cpumac_enclk, 0, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_enclk));

        value  = 0;
        tbl_id = CpuMacCtlResetCtl_t;
        index  = DRV_INS(0, 0);
        cmd    = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_reset));

        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethLane0_f,   &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethLane1_f,   &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethLane2_f,   &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethLane3_f,   &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethRegLane0_f,&value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethRegLane1_f,&value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethRegLane2_f,&value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethRegLane3_f,&value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreCgPcs_f,        &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii0_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii1_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii2_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii3_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs0_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs1_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs2_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs3_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreQuadSgmacReg_f, &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreQuadSgmac_f,    &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSgmac0_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSgmac1_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSgmac2_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSgmac3_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSharedFecReg_f, &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSharedMiiReg_f, &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSharedPcsReg_f, &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreXlgPcs0_f,      &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreXlgPcs1_f,      &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssRxLane0_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssRxLane1_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssRxLane2_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssRxLane3_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssTxLane0_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssTxLane1_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssTxLane2_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssTxLane3_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetSharedFec_f,        &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHss32GUnitWrapperReg_f, &value, &cpumac_reset, 0, 0);
        
        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_reset));
            
        index = DRV_INS(SYS_TMG_CPUMAC_HSS_ID, 0);
        cmd = DRV_IOW(QuadSgmacInit_t, QuadSgmacInit_init_f);
        value = 0;
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));       
        value = 1;
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));
#ifdef EMULATION_ENV
        sal_task_sleep(5000);
#else
        sal_task_sleep(1);
#endif     
        cmd = DRV_IOR(QuadSgmacInitDone_t, QuadSgmacInitDone_initDone_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QuadSgmacInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        
    }
    else
    {
        value  = 1;
        tbl_id = CpuMacCtlResetCtl_t;
        index  = DRV_INS(0, 0);
        cmd    = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_reset));

        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethLane0_f,   &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethLane1_f,   &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethLane2_f,   &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethLane3_f,   &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethRegLane0_f,&value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethRegLane1_f,&value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethRegLane2_f,&value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreAnethRegLane3_f,&value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreCgPcs_f,        &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii0_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii1_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii2_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii3_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs0_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs1_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs2_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs3_f,         &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreQuadSgmacReg_f, &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreQuadSgmac_f,    &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSgmac0_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSgmac1_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSgmac2_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSgmac3_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSharedFecReg_f, &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSharedMiiReg_f, &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSharedPcsReg_f, &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreXlgPcs0_f,      &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreXlgPcs1_f,      &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssRxLane0_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssRxLane1_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssRxLane2_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssRxLane3_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssTxLane0_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssTxLane1_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssTxLane2_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHssTxLane3_f,       &value, &cpumac_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetSharedFec_f,        &value, &cpumac_reset, 0, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_reset));

        value   = 0;
        tbl_id  = CpuMacCtlEnClk_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_enclk));

        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkQuadSgmac_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmac0_f   , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmac1_f   , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmac2_f   , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmac3_f   , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmiiPcs0_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmiiPcs1_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmiiPcs2_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkSgmiiPcs3_f, &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkXfiPcs0_f  , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkXfiPcs1_f  , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkXfiPcs2_f  , &value, &cpumac_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CpuMacCtlEnClk_enClkXfiPcs3_f  , &value, &cpumac_enclk, 0, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_enclk));

        value = 1;      
        tbl_id  = CtcMiscCtlReset_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &misc_reset));

        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlReset_resetCoreCpuMac_f , &value, &misc_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlReset_resetMcu_f        , &value, &misc_reset, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlReset_resetCoreMcuIntf_f, &value, &misc_reset, 0, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &misc_reset));

        value   = 0;
        tbl_id  = CtcMiscCtlClkEn_t;
        cmd     = DRV_IOR(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &misc_enclk));

        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlClkEn_enClkMcu_f , &value, &misc_enclk, 0, 0);
        DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcMiscCtlClkEn_enClkMcuIntf_f        , &value, &misc_enclk, 0, 0);

        cmd    = DRV_IOW(tbl_id,  DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &misc_enclk));

    }
    
    return CTC_E_NONE;    
}

int32
_sys_tmg_mac_set_group_enable(uint8 lchip, uint8 txqm_id, uint8 enable)
{

    if(txqm_id == SYS_TMG_CPUMAC_TXQM_ID)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_cpumac_group_enable(lchip, enable));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_nw_group_enable(lchip, txqm_id, enable));
    }
    
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_dynamic_switch_set_group_power(uint8 lchip, sys_dmps_ds_list_t* p_list, uint8 enable)
{
    uint16 mac_id   = 0;
    uint8  txqm_id      = 0;
    uint16 lsd          = 0;

    SYS_CONDITION_RETURN((!p_list), CTC_E_INVALID_CONFIG);
    lsd = p_list->lsd_list[0];

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, lsd, DMPS_DB_TYPE_MAC, NULL, &mac_id));

    txqm_id = SYS_TMG_GET_TXQM_BY_MAC_ID(mac_id);

    if (enable)
    {
        if (!_sys_tmg_mac_is_power_up(lchip, txqm_id))
        {
            CTC_ERROR_RETURN(_sys_tmg_mac_set_group_enable(lchip, txqm_id, TRUE));
        }
    }
    else
    {
        if (!_sys_tmg_mac_is_power_up(lchip, txqm_id))
        {
            CTC_ERROR_RETURN(_sys_tmg_mac_set_group_enable(lchip, txqm_id, FALSE));
        }
    }
    
    return CTC_E_NONE;
}

///TODO:
int32
_sys_tmg_mac_dynamic_switch_serdes_get_list(uint8 lchip, void* p_serdes_info, void* p_ds_list)
{  
    uint8  is_valid[CTC_CHIP_MAX_SERDES_MODE][CTC_CHIP_MAX_SERDES_OCS_MODE] =
    {
    /*  NONE   11_06  12_12  12_58  27_27  10_6   26_56  26_52   26_9  36_36  36_76  11_06_11 12_58_12 51_56  52_71  20_625 103_12 105_42 */
       {TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_NONE_MODE*/
       {TRUE , TRUE , TRUE , TRUE , FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, TRUE ,   TRUE ,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_XFI_MODE*/
       {TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_SGMII_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_XSGMII_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_QSGMII_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_XAUI_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_DXAUI_MODE*/
       {TRUE , TRUE , TRUE , TRUE , FALSE, TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, TRUE ,   TRUE ,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_XLG_MODE*/
       {TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, TRUE , TRUE , TRUE , TRUE , TRUE , FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_CG_MODE*/
       {TRUE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_2DOT5G_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_USXGMII0_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_USXGMII1_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_USXGMII2_MODE*/
       {TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, TRUE , TRUE , TRUE , TRUE , TRUE , FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_XXVG_MODE*/
       {TRUE , FALSE, FALSE, FALSE, TRUE , FALSE, TRUE , TRUE , TRUE , TRUE , TRUE , FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_LG_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_100BASEFX_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, TRUE , FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_LG_R1_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, TRUE , FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_CG_R2_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, TRUE , FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_CCG_R4_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, TRUE , FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_CDG_R8_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE}, /*CTC_CHIP_SERDES_XLG_R2_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, TRUE }, /*CTC_CHIP_SERDES_CG_R1_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, TRUE }, /*CTC_CHIP_SERDES_CCG_R2_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, TRUE }, /*CTC_CHIP_SERDES_CDG_R4_MODE*/
       {FALSE , FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, TRUE }, /*CTC_CHIP_SERDES_DCCCG_R8_MODE*/
       {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE }, /*CTC_CHIP_SERDES_PHY_MODE*/
       {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,   FALSE,   FALSE, FALSE, FALSE, FALSE, FALSE }, /*CTC_CHIP_SERDES_RGMII_MODE*/
    };
    ctc_chip_serdes_info_t* p_info = (ctc_chip_serdes_info_t*)p_serdes_info;
    sys_dmps_ds_list_t* p_list = (sys_dmps_ds_list_t*)p_ds_list;

    if(!is_valid[p_info->serdes_mode][p_info->overclocking_speed])
    {
        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% The mode is not support! \n");
        return CTC_E_INVALID_CONFIG;
    }

    /* 1. get logical serdes, dport, chan list with dynamic switch */
    p_list->ovclk    = p_info->overclocking_speed;
    p_list->dst_mode = p_info->serdes_mode;
    SYS_DMPS_GET_PORT_SPEED(p_info->serdes_mode, p_list->chan_info.dst_speed_mode);
    CTC_ERROR_RETURN(_sys_tmg_mac_get_dynamic_switch_list(lchip, p_info->serdes_id, p_list));

    /* 2. check param */
    CTC_ERROR_RETURN(_sys_tmg_datapath_dynamic_switch_check(lchip, p_list));

    return CTC_E_NONE;
}

/*skip_get_prop: TRUE - using p_port_info to fill p_api_db instead of get db; 
                 FALSE - get db property to fill p_api_db
p_port_info: source data to fill p_api_db if skip_get_prop is TRUE; else bring db property to caller
*/
int32
_sys_tmg_mac_fill_db_api(uint8 lchip, uint16 dport, uint8 skip_get_prop, 
                                 sys_dmps_db_upt_info_t* p_port_info, sys_dmps_mac_api_db_t* p_api_db)
{
    uint8  mii_idx                      = 0;
    uint8  mac_grp                      = 0;
    uint8  lsd_num                      = 0;
    uint8  if_mode                      = 0;
    uint8  fec_type                     = 0;
    uint8  speed_mode                   = 0;
    uint8  port_type                    = 0;
    uint16 lsd[DMPS_MAX_NUM_PER_MODULE] = {0};
    sys_dmps_db_upt_info_t  port_info = {0};

    CTC_PTR_VALID_CHECK(p_api_db);

    if(skip_get_prop)
    {
        CTC_PTR_VALID_CHECK(p_port_info);
        mii_idx = p_port_info->mac_idx;
        mac_grp = p_port_info->mac_group;
        if_mode = p_port_info->if_mode;
        fec_type = p_port_info->fec_type;
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_IDX);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_GROUP_ID);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_FEC_TYPE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_IDX, mii_idx);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_GROUP_ID, mac_grp);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_FEC_TYPE, fec_type);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, port_type);

        if(NULL != p_port_info)
        {
            sal_memcpy(p_port_info, &port_info, sizeof(sys_dmps_db_upt_info_t));
        }
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_LSD, &lsd_num, lsd));
    p_api_db->core_id     = 0;
    p_api_db->fec_type    = fec_type;
    p_api_db->if_mode     = if_mode;
    p_api_db->speed_mode  = speed_mode;
    p_api_db->mac_grp_idx = mac_grp;
    p_api_db->mac_idx     = mii_idx;
    p_api_db->pcs_grp_idx = mac_grp;
    p_api_db->pcs_idx     = SYS_TMG_GET_INNER_LANE_BY_SERDES(lsd[0]);
    p_api_db->port_type   = port_type;
    /*DMPS_DUMP_PRINT("#### Port %d info #### \n", dport);
    DMPS_DUMP_PRINT("mii_idx: %d\n", mii_idx);
    DMPS_DUMP_PRINT("mac_group: %d\n", mac_grp);
    DMPS_DUMP_PRINT("if_mode: %d\n", if_mode);
    DMPS_DUMP_PRINT("fec_type: %d\n", fec_type);
    DMPS_DUMP_PRINT("lsd: total %u, ", lsd_num);
    uint8 idx;
    for(idx = 0; idx < lsd_num; idx++)
    {
        DMPS_DUMP_PRINT("%d ", lsd[idx]);
    }
    DMPS_DUMP_PRINT("\n");

    DMPS_DUMP_PRINT("################\n");
    DMPS_DUMP_PRINT("mac_grp_idx: %d\n", p_api_db->mac_grp_idx);
    DMPS_DUMP_PRINT("pcs_grp_idx: %d\n", p_api_db->pcs_grp_idx);
    DMPS_DUMP_PRINT("mac_idx:     %d\n", p_api_db->mac_idx);
    DMPS_DUMP_PRINT("pcs_idx:     %d\n", p_api_db->pcs_idx);
    DMPS_DUMP_PRINT("if_mode:     %d\n", if_mode);
    DMPS_DUMP_PRINT("fec_type:    %d\n", fec_type);*/

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_fill_db_api_simplify(uint8 lchip, uint16 mac_id, uint8 if_mode, 
                                             uint8 fec_type, sys_dmps_mac_api_db_t* p_api_db)
{
    CTC_PTR_VALID_CHECK(p_api_db);
    
    p_api_db->core_id     = 0;
    p_api_db->fec_type    = fec_type;
    p_api_db->if_mode     = if_mode;
    p_api_db->mac_grp_idx = (uint8)SYS_TMG_GET_MAC_GROUP(mac_id);
    p_api_db->pcs_grp_idx = (uint8)SYS_TMG_GET_MAC_GROUP(mac_id);
    p_api_db->mac_idx     = (uint8)SYS_TMG_GET_QUAD_MAC_ID(mac_id);
    p_api_db->pcs_idx     = (uint8)SYS_TMG_GET_QUAD_MAC_ID(mac_id);

    //DMPS_DUMP_PRINT("//################\n");
    //DMPS_DUMP_PRINT("//mac_id:      %d\n", mac_id);
    //DMPS_DUMP_PRINT("//mac_grp_idx: %d\n", p_api_db->mac_grp_idx);
    //DMPS_DUMP_PRINT("//pcs_grp_idx: %d\n", p_api_db->pcs_grp_idx);
    //DMPS_DUMP_PRINT("//mac_idx:     %d\n", p_api_db->mac_idx);
    //DMPS_DUMP_PRINT("//pcs_idx:     %d\n", p_api_db->pcs_idx);
    //DMPS_DUMP_PRINT("//if_mode:     %d\n", if_mode);
    //DMPS_DUMP_PRINT("//fec_type:    %d\n", fec_type);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_mii_link_status(uint8 lchip, uint16 dport, uint8 mii_link_type, uint32* p_value)
{
    uint16 lport                        = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u\n", __FUNCTION__, lchip, dport);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    CTC_ERROR_RETURN(sys_usw_dmps_db_dport_2_lport(lchip, dport, &lport));
    if(CTC_E_NONE == sys_usw_phy_get_phy_register_exist(lchip, lport))
    {
        DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_LINK_UP, lchip, &api_db, p_value, TRUE, mii_link_type);
    }
    else
    {
        DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_LINK_UP, lchip, &api_db, p_value, FALSE, mii_link_type);
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_link_up(uint8 lchip, uint16 dport, uint32 is_phy_link, uint8 mii_link_type, uint32* p_is_up)
{
    uint8  port_type   = 0;
    uint8  if_mode     = 0;
    uint16 lport       = 0;
    uint32 an_en       = 0;
    uint32 an_mode     = 0;
    uint32 remote_link = 0;
    uint32 speed       = 0;
    sys_dmps_db_upt_info_t port_info = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,          dport);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, 0);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,    port_type);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);

    CTC_ERROR_RETURN(sys_usw_dmps_db_dport_2_lport(lchip, dport, &lport));

    if(SYS_USW_IS_NETWORK_PORT(port_type))
    {
        /*g_flt_print_en = TRUE;*/
        CTC_ERROR_RETURN(_sys_tmg_mac_get_mii_link_status(lchip, dport, mii_link_type, p_is_up));
        /*g_flt_print_en = FALSE;*/
        if((CTC_CHIP_SERDES_SGMII_MODE== if_mode) || (CTC_CHIP_SERDES_2DOT5G_MODE== if_mode))
        {
            CTC_ERROR_RETURN(_sys_tmg_mac_get_cl37_en(lchip, lport, &an_en));
            if(is_phy_link && an_en)
            {
                CTC_ERROR_RETURN(_sys_tmg_mac_get_cl37_mode(lchip, lport, &an_mode));
                CTC_ERROR_RETURN(_sys_tmg_mac_get_cl37_an_remote_status(lchip, lport, an_mode, &speed, &remote_link));
                if(FALSE == remote_link)
                {
                    *p_is_up = FALSE;
                }
            }
        }
    }
    else
    {
        *p_is_up = FALSE;

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,                 dport);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_LINK_STATUS, ((*p_is_up)?1:0));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));

        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% dport %u is not used \n", dport);
        return CTC_E_INVALID_PORT;
    }
    return CTC_E_NONE;
}

int32
sys_tmg_mac_get_link_up(uint8 lchip, uint16 lport, uint32* p_is_up, uint32 is_phy_link)
{
    uint16 dport = DMPS_INVALID_VALUE_U16;
    sys_dmps_db_upt_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_is_up);
    SYS_MAC_INIT_CHECK();

    if(is_phy_link && (CTC_E_NONE == sys_usw_phy_get_phy_register_exist(lchip, lport)))
    {
        CTC_ERROR_RETURN(sys_usw_phy_get_phy_property(lchip, lport, CTC_PORT_PROP_LINK_UP, (void*)p_is_up));
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_link_up(lchip, dport, is_phy_link, SYS_MAC_MII_LINK_FM, p_is_up));

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,                 dport);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_LINK_STATUS, ((*p_is_up)?1:0));
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_fec(uint8 lchip, uint16 lport, void* p_port_info, uint8 fec_val)
{
    uint8  mac_id                    = 0;
    uint8  if_mode                   = 0;
    sys_dmps_mac_api_db_t     api_db = {0};
    sys_port_api_dmps_info_t* p_info = (sys_port_api_dmps_info_t*)p_port_info;

    DP_DEBUG_FUNCTION_CALLED_PRINT();

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, lport %u, fec_val %u\n", 
        __FUNCTION__, lchip, lport, fec_val);

    mac_id  = p_info->mac_id;
    if_mode = p_info->serdes_info.serdes_mode;

    /*TM-GX dont have RS544 IP*/
    SYS_CONDITION_RETURN(SYS_DMPS_FEC_TYPE_RS544 == fec_val, CTC_E_INVALID_PARAM);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api_simplify(lchip, mac_id, if_mode, fec_val, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FEC, lchip, &api_db);

    CTC_ERROR_RETURN(sys_usw_dmps_db_set_fec_type(lchip, lport, fec_val));

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_sgmac_rst(uint8 lchip, uint16 mac_id, uint32 rst)
{
    uint8  txqm         = SYS_TMG_GET_TXQM_BY_MAC_ID(mac_id);
    uint8  group_id     = SYS_TMG_GET_MAC_GROUP(mac_id);
    uint8  iner_mac     = SYS_TMG_GET_INNER_MAC_ID(mac_id);
    uint8  iner_group   = SYS_TMG_GET_QUAD_MAC_ID(mac_id);
    uint32 tbl_id   = 0;
    uint32 fld_id   = 0;
    uint32 index    = 0;
    uint32 cmd      = 0;
    CtcMacCtlReset_m mac_rst;
    QuadSgmacRxSoftReset_m quad_reset;
    QuadSgmacCfg_m         quad_cfg;
    CpuMacCtlResetCtl_m    cpumac_rst;
    
    if(rst)
    {
        tbl_id  = QuadSgmacRxSoftReset_t;
        dmps_QuadSgmacRxSoftReset_sgmac0RxSoftReset_f(iner_group, fld_id);
        cmd     = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        index   = DRV_INS(group_id, 0);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &quad_reset));
        DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &rst, &quad_reset, group_id, 0);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &quad_reset));
    
        if(group_id == SYS_TMG_MAX_HSS_NUM)
        {
            tbl_id   = CpuMacCtlResetCtl_t;
            dmps_CpuMacCtlResetCtl_resetCoreSgmac0_f(iner_group, fld_id);
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            index   = DRV_INS(0, 0);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_rst));
            DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &rst, &cpumac_rst, 0, 0);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_rst));
            
        }
        else
        {
            tbl_id   = CtcMacCtlReset_t;
            dmps_CtcMacCtlReset_resetCoreSgmac0_f(iner_mac, fld_id);
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            index   = DRV_INS(txqm, 0);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_rst));
            DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &rst, &mac_rst, txqm, 0);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_rst));
        }

    
        tbl_id  = QuadSgmacCfg_t;
        dmps_QuadSgmacCfg_cfgSgmac0TxBufRst_f(iner_group, fld_id);
        cmd     = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        index   = DRV_INS(group_id, 0);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &quad_cfg));
        DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &rst, &quad_cfg, group_id, 0);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &quad_cfg));
    }
    else
    {
        tbl_id  = QuadSgmacCfg_t;
        dmps_QuadSgmacCfg_cfgSgmac0TxBufRst_f(iner_group, fld_id);
        cmd     = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        index   = DRV_INS(group_id, 0);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &quad_cfg));
        DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &rst, &quad_cfg, group_id, 0);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &quad_cfg));

        if(group_id == SYS_TMG_MAX_HSS_NUM)
        {
            tbl_id   = CpuMacCtlResetCtl_t;
            dmps_CpuMacCtlResetCtl_resetCoreSgmac0_f(iner_group, fld_id);
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            index   = DRV_INS(0, 0);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_rst));
            DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &rst, &cpumac_rst, 0, 0);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_rst));
            
        }
        else
        {
            tbl_id   = CtcMacCtlReset_t;
            dmps_CtcMacCtlReset_resetCoreSgmac0_f(iner_mac, fld_id);
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            index   = DRV_INS(txqm, 0);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_rst));
            DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &rst, &mac_rst, txqm, 0);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_rst));
        }

        tbl_id  = QuadSgmacRxSoftReset_t;
        dmps_QuadSgmacRxSoftReset_sgmac0RxSoftReset_f(iner_group, fld_id);
        cmd     = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        index   = DRV_INS(group_id, 0);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &quad_reset));
        DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &rst, &quad_reset, group_id, 0);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &quad_reset));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_port_hss_tx_rst(uint8 lchip, uint16 lport, uint32 rst)
{
    uint8  idx;
    uint16 dport                        = 0;
    uint8  psd_num                      = 0;
    uint16 psd[DMPS_MAX_NUM_PER_MODULE] = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_PSD, &psd_num, psd));

    for(idx = 0; idx < psd_num; idx++)
    {
        CTC_ERROR_RETURN(sys_tmg_serdes_set_hss_tx_rst(lchip, psd[idx], rst));
    }

    return CTC_E_NONE;
}

#ifndef EMULATION_ENV
int32
_sys_tmg_mac_set_port_serdes_tx_en(uint8 lchip, uint16 lport, uint8 en)
{
    uint16 dport = 0;
    uint8  idx = 0;
    uint8  serdes_num = 0;
    uint16 psd[DMPS_MAX_NUM_PER_MODULE] = {0};
    uint8 if_mode = CTC_CHIP_SERDES_NONE_MODE;
    sys_dmps_db_upt_info_t port_info             = {0};   
    uint16 delay = 0;

    SYS_CONDITION_RETURN((0 != SDK_WORK_PLATFORM), CTC_E_NONE);

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,               dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);

    /*when serdes disable, SGMII delay 2000 times (about 40ms based on CPU frequency) to ensure LP device link down*/
    delay= (((CTC_CHIP_SERDES_SGMII_MODE == if_mode) || (CTC_CHIP_SERDES_2DOT5G_MODE == if_mode)) && (0 == SDK_WORK_PLATFORM)) ? 
                        2000 : 1;

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_PSD, &serdes_num, psd));

    do
    {
        for(idx = 0; idx < serdes_num; idx++)
        {
            CTC_ERROR_RETURN(sys_usw_dmps_serdes_set_lane_en(lchip, psd[idx], DMPS_TX, FALSE));
        }
        
    }while(delay-- && FALSE == en);
    
    return CTC_E_NONE;
}
#endif

int32
_sys_tmg_mac_set_macpcs_en(uint8 lchip, uint16 lport, uint8 enable)
{
    uint8  an_en                     = 0;
    uint8  if_mode                   = 0;
    uint8  fec_type                  = 0;
    uint16 mac_id                    = 0;
    uint16 dport                     = 0;
    uint32 link_mode                 = 0;
    sys_dmps_db_upt_info_t port_info = {0};
    sys_dmps_mac_api_db_t     api_db = {0};

    dport = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_AN_EN);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN, an_en);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_fec_type(lchip, lport, &fec_type));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode_by_dport(lchip, dport, &link_mode));

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api_simplify(lchip, mac_id, if_mode, fec_type, &api_db));

    /* HSS/FEC/PCS/MII/Sgmac reset or release */
    if(enable)
    {
        DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MAC_TX_EN, lchip, &api_db, 1);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_sgmac_rst(lchip, mac_id, 0));
        if((LINK_MODE_STDALONE == link_mode) || (1 == an_en))
        {
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MAC_RX_EN, lchip, &api_db, 1);
        }
        else
        {
            CTC_ERROR_RETURN(_sys_tmg_mac_set_pcs_rst(lchip, dport, DMPS_RX, 0));
        }
        if (1 == an_en)
        {
            CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_anlt_en_msg(lchip, dport));
        }
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_hss_tx_rst(lchip, lport, 0));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_hss_tx_rst(lchip, lport, 1));
        DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MAC_RX_EN, lchip, &api_db, 0);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_sgmac_rst(lchip, mac_id, 1));
        DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MAC_TX_EN, lchip, &api_db, 0);
    }

    return CTC_E_NONE;
}

int32
sys_tmg_mac_set_mac_en(uint8 lchip, uint16 lport, void* p_port_info, uint8 enable, uint8 db_upt_flag)
{
    uint8  db_an_en                  = 0;
    uint8  db_mac_en                 = 0;
    uint16 dport                     = 0;
    sys_port_api_dmps_info_t* p_info = (sys_port_api_dmps_info_t*)p_port_info;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, lport %u, enable %u, db_upt_flag %u\n", 
        __FUNCTION__, lchip, lport, enable, db_upt_flag);

    CTC_PTR_VALID_CHECK(p_info);

    DP_DEBUG_FUNCTION_CALLED_PRINT();

#ifdef TMG_SERDES_SIM
    g_print_tbl = 1;
#endif

    dport = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    db_mac_en =  p_info->mac_en;
    db_an_en  =  p_info->auto_neg_en;

    /*g_flt_print_en = TRUE;*/

    if(1 == db_mac_en && 0 == db_upt_flag && 1 == enable && 0 == db_an_en)
    {
        //CTC_ERROR_RETURN(_sys_at_mac_chk_serdes_pll_ready(lchip, dport));
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macpcs_en(lchip, dport, TRUE));
#ifndef EMULATION_ENV
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, dport, TRUE));
#endif
    }
    else if(1 == db_mac_en && 0 == db_upt_flag && 0 == enable && 0 == db_an_en)
    {
#ifndef EMULATION_ENV
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, dport, TRUE));
#endif
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macpcs_en(lchip, dport, FALSE));
    }
    else if(1 == db_mac_en && 0 == db_upt_flag && 0 == enable && 1 == db_an_en)
    {
#ifndef EMULATION_ENV
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, dport, TRUE));
#endif
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macpcs_en(lchip, dport, FALSE));
    }
    else if(1 == db_mac_en && 0 == db_upt_flag && 1 == enable && 1 == db_an_en)
    {
        //CTC_ERROR_RETURN(_sys_at_mac_chk_serdes_pll_ready(lchip, dport));
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macpcs_en(lchip, dport, TRUE));
#ifndef EMULATION_ENV
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, dport, TRUE));
#endif
    }
    else if(1 == db_mac_en && 1 == db_upt_flag && 0 == enable && 0 == db_an_en)
    {
#ifndef EMULATION_ENV
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, dport, TRUE));
#endif
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macpcs_en(lchip, dport, FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_mac_en(lchip, lport, FALSE));
    }
    else if(1 == db_mac_en && 1 == db_upt_flag && 0 == enable && 1 == db_an_en)
    {
#ifndef EMULATION_ENV
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, dport, TRUE));
#endif
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macpcs_en(lchip, dport, FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_switch_off_msg(lchip, dport));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_mac_en(lchip, lport, FALSE));
    }
    else if(0 == db_mac_en && 1 == db_upt_flag && 1 == enable && 0 == db_an_en)
    {
        //CTC_ERROR_RETURN(_sys_at_mac_chk_serdes_pll_ready(lchip, dport));
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macpcs_en(lchip, dport, TRUE));
#ifndef EMULATION_ENV
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, dport, TRUE));
#endif
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_mac_en(lchip, lport, TRUE));
    }   
    else if(0 == db_mac_en && 1 == db_upt_flag && 1 == enable && 1 == db_an_en)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_anlt_en_msg(lchip, dport));
#ifndef EMULATION_ENV
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, dport, TRUE));
#endif
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_mac_en(lchip, lport, TRUE));
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    DP_DEBUG_FUNCTION_RETURN_PRINT();

#ifdef TMG_SERDES_SIM
    g_print_tbl = 0;
#endif

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_unidir_en(uint8 lchip, uint16 dport, uint32 value)
{
    uint16 lport                        = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, value %u\n", __FUNCTION__, lchip, dport, value);

    CTC_ERROR_RETURN(sys_usw_dmps_db_dport_2_lport(lchip, dport, &lport));
    if (CTC_E_NONE == sys_usw_phy_get_phy_register_exist(lchip, lport))
    {
        CTC_ERROR_RETURN(sys_usw_phy_set_phy_property(lchip, lport, CTC_PORT_PROP_UNIDIR_EN, (void*)&value));
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_UNDIR_EN, lchip, &api_db, value ? TRUE : FALSE);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_unidir_en(uint8 lchip, uint16 dport, uint32* p_value)
{
    uint16 lport                        = 0;
    uint32 value                        = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u\n", __FUNCTION__, lchip, dport);

    CTC_ERROR_RETURN(sys_usw_dmps_db_dport_2_lport(lchip, dport, &lport));
    if (CTC_E_NONE == sys_usw_phy_get_phy_register_exist(lchip, lport))
    {
        CTC_ERROR_RETURN(sys_usw_phy_get_phy_property(lchip, lport, CTC_PORT_PROP_UNIDIR_EN, (void*)(&value)));
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_UNDIR_EN, lchip, &api_db, p_value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_parallel_detect_en(uint8 lchip, uint16 dport, uint32 value)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, value %u\n", __FUNCTION__, lchip, dport, value);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_PARALLEL_DETECT_EN, lchip, &api_db, value ? TRUE : FALSE);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_parallel_detect_en(uint8 lchip, uint16 dport, uint32* p_value)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u\n", __FUNCTION__, lchip, dport);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_PARALLEL_DETECT_EN, lchip, &api_db, p_value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_cl37_mode(uint8 lchip, uint16 lport, uint32 value)
{
    uint16 dport                        = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, value %u\n", __FUNCTION__, lchip, dport, value);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    SYS_CONDITION_RETURN(!SYS_MAC_IS_MODE_SUPPORT_CL37(api_db.if_mode), CTC_E_INVALID_PARAM);

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_CL37_MODE, lchip, &api_db, value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_cl37_mode(uint8 lchip, uint16 lport, uint32* p_mode)
{
    uint32 value                        = 0;
    uint16 dport                        = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, value %u\n", __FUNCTION__, lchip, dport, value);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    SYS_CONDITION_RETURN(!SYS_MAC_IS_MODE_SUPPORT_CL37(api_db.if_mode), CTC_E_INVALID_PARAM);

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_CL37_MODE, lchip, &api_db, &value);
    
    SYS_USW_VALID_PTR_WRITE(p_mode, value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_cl37_en(uint8 lchip, uint16 lport, uint32 value)
{
    uint32 unidir                       = 0;
    uint16 dport                        = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, value %u\n", __FUNCTION__, lchip, dport, value);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    SYS_CONDITION_RETURN(!SYS_MAC_IS_MODE_SUPPORT_CL37(api_db.if_mode), CTC_E_INVALID_PARAM);

    CTC_ERROR_RETURN(_sys_tmg_mac_get_unidir_en(lchip, dport, &unidir));
    SYS_CONDITION_RETURN(((value == TRUE) && (unidir == TRUE)), CTC_E_INVALID_PARAM);

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_CL37_EN, lchip, &api_db, value ? TRUE : FALSE);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_cl37_en(uint8 lchip, uint16 lport, uint32* p_value)
{
    uint16 dport                        = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u\n", __FUNCTION__, lchip, dport);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    SYS_CONDITION_RETURN(!SYS_MAC_IS_MODE_SUPPORT_CL37(api_db.if_mode), CTC_E_INVALID_PARAM);

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_CL37_EN, lchip, &api_db, p_value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_cl37_speed(uint8 lchip, uint16 lport, uint8 value)
{
    uint16 mac_id   = 0;
    uint16 dport    = 0;
    //uint8  if_mode  = 0;
    sys_dmps_db_upt_info_t port_info = {0}; 

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    //DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);

    CTC_ERROR_RETURN(sys_usw_dmps_db_set_speed_mode(lchip, lport, value));
    CTC_ERROR_RETURN(_sys_tmg_mac_set_mac_config(lchip, mac_id));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_cl37_flowctl_ability(uint8 lchip, uint16 dport, uint32 capability)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u\n", __FUNCTION__, lchip, dport);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    SYS_CONDITION_RETURN(!SYS_MAC_IS_MODE_SUPPORT_CL37(api_db.if_mode), CTC_E_INVALID_PARAM);

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FLOWCTL_ABILITY, lchip, &api_db, capability);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_cl37_flowctl_ability_local(uint8 lchip, uint16 dport, uint32* p_value)
{
    sys_dmps_mac_api_db_t   api_db      = {0};
    uint32 value                        = 0;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u\n", __FUNCTION__, lchip, dport);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    if(!SYS_MAC_IS_MODE_SUPPORT_CL37(api_db.if_mode))
    {
        SYS_USW_VALID_PTR_WRITE(p_value, 0);
        return CTC_E_NONE;
    }

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_CL37_FLOWCTL_ABILITY_LOCAL, lchip, &api_db, &value);

    SYS_USW_VALID_PTR_WRITE(p_value, value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_cl37_flowctl_ability_remote(uint8 lchip, uint16 dport, uint32* p_value)
{
    sys_dmps_mac_api_db_t   api_db      = {0};
    uint32 value                        = 0;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u\n", __FUNCTION__, lchip, dport);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    if(!SYS_MAC_IS_MODE_SUPPORT_CL37(api_db.if_mode))
    {
        SYS_USW_VALID_PTR_WRITE(p_value, 0);
        return CTC_E_NONE;
    }

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_CL37_FLOWCTL_ABILITY_REMOTE, lchip, &api_db, &value);

    SYS_USW_VALID_PTR_WRITE(p_value, value);

    return CTC_E_NONE;   
}

int32
sys_tmg_mac_set_cl73_en(uint8 lchip, uint16 lport, uint32 enable, uint8 restart)
{  
    uint16 dport = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "dport", dport);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "enable", enable);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "restart", restart);

    /* upd soft sw */
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_cl73_en(lchip, lport, enable));

    /* Trigger ANLT_EN or ANLT_SM_OFF Event */
    CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_cl73_en_event(lchip, dport, enable));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_cl73_reg_acc_check(uint8 lchip, uint16 serdes_id, uint32 address, uint32 io_select)
{
    uint8  hss_id    = 0;
    uint32 tbl_id    = 0;
    uint32 fld_id    = 0;
    uint32 index     = 0;
    uint32 cmd       = 0;
    uint32 status    = 0;
    uint32 data      = 0;

    Hss32GAnethAccStatus_m  acc_status;

#ifdef EMULATION_ENV
        if(!SYS_TMG_PSD_WITH_HSS32G_MODULE(serdes_id))
        {
            return CTC_E_NONE;
        }
#endif

    hss_id      = SYS_TMG_GET_HSS_ID_BY_SERDES(serdes_id);

    index  = DRV_INS(hss_id, 0);
    tbl_id = Hss32GAnethAccStatus_t;
    fld_id = Hss32GAnethAccStatus_statusAneth_f;
    cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &acc_status));
    DRV_IOR_FIELD(lchip, tbl_id, fld_id, &status, &acc_status);

    if(!io_select)
    {
        fld_id = Hss32GAnethAccStatus_rdDataAneth_f;
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &data, &acc_status);
        if(0xDEAD1111 == data)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% return data 0xDEAD1111, which is invalid\n");
            return CTC_E_HW_FAIL;
        }
    }

    if((status & (1 << TMG_CL73_ACC_IO_TYPE)) ^ io_select)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% status_IO_type %d don't match ctl_IO_type %d \n",
            status & 0x1, io_select);
        return CTC_E_INVALID_PARAM;
    }

    if(CTC_IS_BIT_SET(status, TMG_CL73_ACC_IO_ERR))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% IO ack error \n");
        return CTC_E_HW_FAIL;
    }

    if(CTC_IS_BIT_SET(status, TMG_CL73_ACC_IO_OVERLAP))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% IO overlap error \n");
        return CTC_E_HW_FAIL;
    }

    if(!CTC_IS_BIT_SET(status, TMG_CL73_ACC_IO_DONE))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% IO not done \n");
        return CTC_E_HW_BUSY;
    }

    if(CTC_IS_BIT_SET(status, TMG_CL73_ACC_IO_TIMEOUT))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% IO timeout \n");
        return CTC_E_HW_TIME_OUT;
    }

    if((status >> 5) & (~address))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% status_address %d don't match ctl_address %d \n",
            status >> 5, address);
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32 
_sys_tmg_mac_cl73_reg_acc_init(uint8 lchip, uint16 serdes_id, uint32 en)
{
    uint8  hss_id    = 0;
    uint8  lane_idx  = 0;
    uint32 tbl_id    = 0;
    uint32 fld_id[3] = {0};
    uint32 index     = 0;
    uint32 cmd       = 0;
    uint32 value     = en ? 0: 1;

    Hss32GReset_m  hss_rst;

    hss_id      = SYS_TMG_GET_HSS_ID_BY_SERDES(serdes_id);
    lane_idx    = SYS_TMG_GET_INNER_LANE_BY_SERDES(serdes_id);

    index     = DRV_INS(hss_id, 0);

    tbl_id    = Hss32GReset_t;
    fld_id[0] = Hss32GReset_cfgPhyRegAccReset_f;
    dmps_Hss32GReset_resetCoreAnethRegL0_f(lane_idx, fld_id[1]);
    dmps_Hss32GReset_resetCoreAnethL0_f(lane_idx, fld_id[2]);
    cmd       = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hss_rst));

    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id[0], &value, &hss_rst, hss_id, 0);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id[1], &value, &hss_rst, hss_id, 0);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id[2], &value, &hss_rst, hss_id, 0);

    cmd       = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &hss_rst));

    return CTC_E_NONE;
}

int32 _sys_tmg_mac_cl73_read_reg(uint8 lchip, uint16 serdes_id, uint32 address, uint32* p_data)
{
    uint8  hss_id     = 0;
    uint8  lane_idx   = 0;
    int32  ret        = 0;
    uint32 index      = 0;
    uint32 cmd        = 0;
    uint32 addr_write = 0;
    uint32 cmd_write  = READ_REG;
    uint32 tbl_id     = 0;
    uint32 fld_id[3]  = {0};
    uint32 acc_timeout = 0;
    Hss32GAnethAccCtl_m       acc_ctl;
    Hss32GAnethAccStatus_m    acc_status;

    hss_id      = SYS_TMG_GET_HSS_ID_BY_SERDES(serdes_id);
    lane_idx    = SYS_TMG_GET_INNER_LANE_BY_SERDES(serdes_id);
    addr_write  = address | (lane_idx << 24);

    /* write read command in ctl reg */
    index     = DRV_INS(hss_id, 0);

    tbl_id    = Hss32GAnethAccCtl_t;
    fld_id[0] = Hss32GAnethAccCtl_regAddrAneth_f;
    fld_id[1] = Hss32GAnethAccCtl_wrCmdAneth_f;
    cmd       = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &acc_ctl));

    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id[0], &addr_write, &acc_ctl, hss_id, 0);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id[1], &cmd_write, &acc_ctl, hss_id, 0);

    cmd       = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &acc_ctl));

    for(acc_timeout = 0; acc_timeout < SYS_TMG_CL73_ACC_TIMEOUT; acc_timeout++)
    {
        ret = _sys_tmg_mac_cl73_reg_acc_check(lchip, serdes_id, addr_write, cmd_write);
        if(CTC_E_NONE == ret)
        {
            break;
        }
        else if(CTC_E_HW_BUSY == ret)
        {
            continue;
        }
        else
        {
            return ret;
        }
    }

    if(SYS_TMG_CL73_ACC_TIMEOUT == acc_timeout)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% after acc_check 10000 times,there's still error \n");
        return CTC_E_HW_TIME_OUT;
    }

    /* read data in status reg*/
    index     = DRV_INS(hss_id, 0);
    tbl_id    = Hss32GAnethAccStatus_t;
    fld_id[2] = Hss32GAnethAccStatus_rdDataAneth_f;
    cmd       = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &acc_status));
    DRV_IOR_FIELD(lchip, tbl_id, fld_id[2], p_data, &acc_status);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_cl73_write_reg(uint8 lchip, uint16 serdes_id, uint32 address, uint32 data)
{
    uint8  hss_id     = 0;
    uint8  lane_idx   = 0;
    int32  ret        = 0;
    uint32 index      = 0;
    uint32 cmd        = 0;
    uint32 addr_write = 0;
    uint32 cmd_write  = WRITE_REG;
    uint32 tbl_id     = 0;
    uint32 fld_id[3]  = {0};
    uint32 acc_timeout = 0;
    Hss32GAnethAccCtl_m       acc_ctl;

    hss_id      = SYS_TMG_GET_HSS_ID_BY_SERDES(serdes_id);
    lane_idx    = SYS_TMG_GET_INNER_LANE_BY_SERDES(serdes_id);
    addr_write  = address | (lane_idx << 24);

    /* write write command in ctl reg */
    index     = DRV_INS(hss_id, 0);

    tbl_id    = Hss32GAnethAccCtl_t;
    fld_id[0] = Hss32GAnethAccCtl_regAddrAneth_f;
    fld_id[1] = Hss32GAnethAccCtl_wrCmdAneth_f;
    fld_id[2] = Hss32GAnethAccCtl_wrDataAneth_f;
    cmd       = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &acc_ctl));

    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id[0], &addr_write, &acc_ctl, hss_id, 0);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id[1], &cmd_write, &acc_ctl, hss_id, 0);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id[2], &data, &acc_ctl, hss_id, 0);

    cmd       = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &acc_ctl));

    for(acc_timeout = 0; acc_timeout < SYS_TMG_CL73_ACC_TIMEOUT; acc_timeout++)
    {
        ret = _sys_tmg_mac_cl73_reg_acc_check(lchip, serdes_id, addr_write, cmd_write);
        if(CTC_E_NONE == ret)
        {
            break;
        }
        else if(CTC_E_HW_BUSY == ret)
        {
            continue;
        }
        else
        {
            return ret;
        }
    }

    if(SYS_TMG_CL73_ACC_TIMEOUT == acc_timeout)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% after acc_check 10000 times,there's still error \n");
        return CTC_E_HW_TIME_OUT;
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_cl73_read_field(uint8 lchip, uint16 serdes_id, _sys_tmg_cl73_field_t* p_field_info, uint32* p_data)
{
    uint32 reg_val = 0;

    CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_reg(lchip, serdes_id, p_field_info->address, &reg_val));

    *p_data = (reg_val & p_field_info->mask) >> p_field_info->lo_bit;

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_cl73_write_field(uint8 lchip, uint16 serdes_id, _sys_tmg_cl73_field_t* p_field_info, uint32 data)
{
    uint32 reg_val  = 0;

    CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_reg(lchip, serdes_id, p_field_info->address, &reg_val));

    reg_val = (reg_val & p_field_info->retain_mask) | (data << p_field_info->lo_bit);

    CTC_ERROR_RETURN(_sys_tmg_mac_cl73_write_reg(lchip, serdes_id, p_field_info->address, reg_val));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_capability(uint8 lchip, uint16 lport, ctc_port_capability_type_t type, uint32 value)
{
    uint16 dport = 0;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set port capability, lport:%u, type:%d value:0x%x!\n", lport, type, value);

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    switch (type)
    {
        case CTC_PORT_CAP_TYPE_LOCAL_PAUSE_ABILITY:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_cl37_flowctl_ability(lchip, dport, value));
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;

}

int32
_sys_tmg_mac_get_cl73_capability(uint8 lchip, uint16 dport, uint32* p_capability)
{
    uint8  if_mode   = 0;
    uint8  port_type = 0;
    sys_dmps_db_upt_info_t port_info = {0};

    CTC_PTR_VALID_CHECK(p_capability);
    CTC_PTR_VALID_CHECK(p_capability + 1);

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,             dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,    port_type);
    
    SYS_CONDITION_RETURN(!SYS_USW_IS_NETWORK_PORT(port_type), CTC_E_INVALID_PORT);

    switch(if_mode)
    {
        case CTC_CHIP_SERDES_XXVG_MODE:
        case CTC_CHIP_SERDES_XFI_MODE:
            *p_capability = (CTC_PORT_CL73_10GBASE_KR |
                             CTC_PORT_CL73_25GBASE_KRS |
                             CTC_PORT_CL73_25GBASE_CRS |
                             CTC_PORT_CL73_25GBASE_KR |
                             CTC_PORT_CL73_25GBASE_CR |
                             CTC_PORT_CL73_25G_RS_FEC_REQUESTED |
                             CTC_PORT_CL73_25G_BASER_FEC_REQUESTED |
                             CTC_PORT_CSTM_25GBASE_KR1 |
                             CTC_PORT_CSTM_25GBASE_CR1 |
                             CTC_PORT_CSTM_RS_FEC_ABILITY |
                             CTC_PORT_CSTM_BASER_FEC_ABILITY |
                             CTC_PORT_CSTM_RS_FEC_REQUESTED |
                             CTC_PORT_CSTM_BASER_FEC_REQUESTED |
                             CTC_PORT_CL73_FEC_ABILITY |
                             CTC_PORT_CL73_FEC_REQUESTED);
            break;
        case CTC_CHIP_SERDES_LG_MODE:
            *p_capability = (CTC_PORT_CSTM_50GBASE_KR2 |
                             CTC_PORT_CSTM_50GBASE_CR2 |
                             CTC_PORT_CSTM_RS_FEC_ABILITY |
                             CTC_PORT_CSTM_BASER_FEC_ABILITY |
                             CTC_PORT_CSTM_RS_FEC_REQUESTED |
                             CTC_PORT_CSTM_BASER_FEC_REQUESTED |
                             CTC_PORT_CL73_FEC_ABILITY |
                             CTC_PORT_CL73_FEC_REQUESTED);
            break;
        case CTC_CHIP_SERDES_CG_MODE:
        case CTC_CHIP_SERDES_XLG_MODE:
            *p_capability = (CTC_PORT_CL73_40GBASE_KR4 |
                             CTC_PORT_CL73_40GBASE_CR4 |
                             CTC_PORT_CL73_100GBASE_KR4 |
                             CTC_PORT_CL73_100GBASE_CR4 |
                             CTC_PORT_CL73_25G_RS_FEC_REQUESTED |
                             CTC_PORT_CL73_FEC_ABILITY |
                             CTC_PORT_CL73_FEC_REQUESTED |
                             CTC_PORT_CL73_25G_BASER_FEC_REQUESTED);
            break;
        default:
            *p_capability = 0;
            break;
    }
    
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_cl73_ability(uint8 lchip, uint16 dport, uint32 type, void* p_ability)
{
    uint32* ability   = (uint32*)p_ability;
    uint8  cnt        = 0;
    uint8  serdes_num = 0;
    uint8  port_type  = 0;
    uint16 physic_serdes[DMPS_MAX_NUM_PER_MODULE] = {0};
    sys_dmps_db_upt_info_t port_info              = {0};
    sys_datapath_an_ability_t sys_total_ability   = {0};
    sys_datapath_an_ability_t serdes_ability[DMPS_MAX_NUM_PER_MODULE];

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"dport:%d\n", dport);

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,                 dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,        port_type);

    if (!SYS_USW_IS_NETWORK_PORT(port_type))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% dport %d is not used \n", dport);
        return CTC_E_INVALID_PORT;
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_PSD, &serdes_num, physic_serdes));

    /* if auto_neg_ok, should get ability */
    if (type)
    {
        for(cnt = 0; cnt < serdes_num; cnt++)
        {
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_MON_LP_NEXT_PAGE1_47_32), &serdes_ability[cnt].np1_ability1));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_MON_LP_NEXT_PAGE1_31_0), &serdes_ability[cnt].np1_ability0));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_MON_LP_NEXT_PAGE0_47_32), &serdes_ability[cnt].np0_ability1));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_MON_LP_NEXT_PAGE0_31_0), &serdes_ability[cnt].np0_ability0));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_MON_LP_BASE_PAGE_47_32), &serdes_ability[cnt].base_ability1));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_MON_LP_BASE_PAGE_31_0), &serdes_ability[cnt].base_ability0));
        }
    }
    else
    {
        for(cnt = 0; cnt < serdes_num; cnt++)
        {
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_NEXT_PAGE_TX1_47_32), &serdes_ability[cnt].np1_ability1));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_NEXT_PAGE_TX1_31_0), &serdes_ability[cnt].np1_ability0));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_NEXT_PAGE_TX0_47_32), &serdes_ability[cnt].np0_ability1));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_NEXT_PAGE_TX0_31_0), &serdes_ability[cnt].np0_ability0));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_BASE_PAGE_47_32), &serdes_ability[cnt].base_ability1));
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, physic_serdes[cnt], TMG_CL73_REG_STR(TMG_CL73_BASE_PAGE_31_0), &serdes_ability[cnt].base_ability0));
        }
    }

    sal_memset(&sys_total_ability, 0, sizeof(sys_datapath_an_ability_t));

    for(cnt = 0; cnt < serdes_num; cnt++)
    {
        sys_total_ability.base_ability0 |= serdes_ability[cnt].base_ability0;
        sys_total_ability.base_ability1 |= serdes_ability[cnt].base_ability1;
        sys_total_ability.np0_ability0  |= serdes_ability[cnt].np0_ability0;
        sys_total_ability.np0_ability1  |= serdes_ability[cnt].np0_ability1;
        sys_total_ability.np1_ability0  |= serdes_ability[cnt].np1_ability0;
        sys_total_ability.np1_ability1  |= serdes_ability[cnt].np1_ability1;
    }
    
    if(sys_total_ability.base_ability0 & SYS_PORT_CL73_10GBASE_KR)
    {
        *ability |= (CTC_PORT_CL73_10GBASE_KR);
    }
    if(sys_total_ability.base_ability0 & SYS_PORT_CL73_40GBASE_KR4)
    {
        *ability |= (CTC_PORT_CL73_40GBASE_KR4);
    }
    if(sys_total_ability.base_ability0 & SYS_PORT_CL73_40GBASE_CR4)
    {
        *ability |= (CTC_PORT_CL73_40GBASE_CR4);
    }
    if(sys_total_ability.base_ability0 & SYS_PORT_CL73_100GBASE_KR4)
    {
        *ability |= (CTC_PORT_CL73_100GBASE_KR4);
    }
    if(sys_total_ability.base_ability0 & SYS_PORT_CL73_100GBASE_CR4)
    {
        *ability |= (CTC_PORT_CL73_100GBASE_CR4);
    }
    if(sys_total_ability.base_ability0 & SYS_PORT_CL73_25GBASE_KR_S)
    {
        *ability |= (CTC_PORT_CL73_25GBASE_KRS);
    }
    if(sys_total_ability.base_ability0 & SYS_PORT_CL73_25GBASE_KR)
    {
        *ability |= (CTC_PORT_CL73_25GBASE_KR);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_50GBASE_KR)
    {
        *ability |= (CTC_PORT_CL73_50GBASE_KR);
        *ability |= (CTC_PORT_CL73_50GBASE_CR);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_100GBASE_KR2)
    {
        *ability |= (CTC_PORT_CL73_100GBASE_KR2);
        *ability |= (CTC_PORT_CL73_100GBASE_CR2);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_200GBASE_KR4)
    {
        *ability |= (CTC_PORT_CL73_200GBASE_KR4);
        *ability |= (CTC_PORT_CL73_200GBASE_CR4);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_25G_RS_FEC_REQ)
    {
        *ability |= (CTC_PORT_CL73_25G_RS_FEC_REQUESTED);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_25G_BASER_FEC_REQ)
    {
        *ability |= (CTC_PORT_CL73_25G_BASER_FEC_REQUESTED);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_FEC_SUP)
    {
        *ability |= (CTC_PORT_CL73_FEC_ABILITY);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_FEC_REQ)
    {
        *ability |= (CTC_PORT_CL73_FEC_REQUESTED);
    }
    if(sys_total_ability.np1_ability0 & SYS_PORT_CSTM_25GBASE_KR1)
    {
        *ability |= (CTC_PORT_CSTM_25GBASE_KR1);
    }
    if(sys_total_ability.np1_ability0 & SYS_PORT_CSTM_25GBASE_CR1)
    {
        *ability |= (CTC_PORT_CSTM_25GBASE_CR1);
    }
    if(sys_total_ability.np1_ability0 & SYS_PORT_CSTM_50GBASE_KR2)
    {
        *ability |= (CTC_PORT_CSTM_50GBASE_KR2);
    }
    if(sys_total_ability.np1_ability0 & SYS_PORT_CSTM_50GBASE_CR2)
    {
        *ability |= (CTC_PORT_CSTM_50GBASE_CR2);
    }
    if(sys_total_ability.np1_ability1 & SYS_PORT_CSTM_400GBASE_CR8)
    {
        *ability |= (CTC_PORT_CSTM_400GBASE_CR8);
    }
    if(sys_total_ability.np1_ability1 & SYS_PORT_CSTM_CL91_FEC_SUP)
    {
        *ability |= (CTC_PORT_CSTM_RS_FEC_ABILITY);
    }
    if(sys_total_ability.np1_ability1 & SYS_PORT_CSTM_CL74_FEC_SUP)
    {
        *ability |= (CTC_PORT_CSTM_BASER_FEC_ABILITY);
    }
    if(sys_total_ability.np1_ability1 & SYS_PORT_CSTM_CL91_FEC_REQ)
    {
        *ability |= (CTC_PORT_CSTM_RS_FEC_REQUESTED);
    }
    if(sys_total_ability.np1_ability1 & SYS_PORT_CSTM_CL74_FEC_REQ)
    {
        *ability |= (CTC_PORT_CSTM_BASER_FEC_REQUESTED);
    }
    if(sys_total_ability.np1_ability1 & SYS_PORT_CSTM_LF1_50GR1)
    {
        *ability |= (CTC_PORT_CSTM_LF1_50GR1);
    }
    if(sys_total_ability.np1_ability1 & SYS_PORT_CSTM_LF2_100GR2)
    {
        *ability |= (CTC_PORT_CSTM_LF2_100GR2);
    }
    if(sys_total_ability.np1_ability1 & SYS_PORT_CSTM_LF3_200GR4)
    {
        *ability |= (CTC_PORT_CSTM_LF3_200GR4);
    }
    if(sys_total_ability.np1_ability1 & SYS_PORT_CSTM_LL_RS_FEC_REQ)
    {
        *ability |= (CTC_PORT_CSTM_LL_RS_FEC_REQ);
    }
    /*ctc_port_cl73_ability_ext_t*/
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_100GBASE_KR1)
    {
        *(ability+1) |= (CTC_PORT_CL73_100GBASE_KR1);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_100GBASE_CR1)
    {
        *(ability+1) |= (CTC_PORT_CL73_100GBASE_CR1);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_200GBASE_KR2)
    {
        *(ability+1) |= (CTC_PORT_CL73_200GBASE_KR2);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_200GBASE_CR2)
    {
        *(ability+1) |= (CTC_PORT_CL73_200GBASE_CR2);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_400GBASE_KR4)
    {
        *(ability+1) |= (CTC_PORT_CL73_400GBASE_KR4);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_400GBASE_CR4)
    {
        *(ability+1) |= (CTC_PORT_CL73_400GBASE_CR4);
    }
    if(sys_total_ability.base_ability1 & SYS_PORT_CL73_100G_RS_FEC_INT_REQ)
    {
        *(ability+1) |= (CTC_PORT_CL73_100G_RS_FEC_INT_REQUESTED);
    }
    if(sys_total_ability.np1_ability0 & SYS_PORT_CSTM_800GETC_KR8)
    {
        *(ability+1) |= (CTC_PORT_CSTM_800G_ETC_KR8);
    }
    if(sys_total_ability.np1_ability0 & SYS_PORT_CSTM_800GETC_CR8)
    {
        *(ability+1) |= (CTC_PORT_CSTM_800G_ETC_CR8);
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_serdes_info_capability(uint8 lchip, uint16 dport, ctc_port_serdes_info_t* p_value)
{
    uint8  idx        = 0;
    uint8  serdes_num = 0;
    uint8  if_mode    = 0;
    uint8  ocs_mode   = 0;
    uint16 serdes_id  = 0;
    sys_dmps_db_upt_info_t port_info = {0};
    uint16 physic_serdes[DMPS_MAX_NUM_PER_MODULE] = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"dport:%d\n", dport);

    SYS_MAC_INIT_CHECK();

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,             dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PSD_OCS);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PSD_OCS, ocs_mode);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, 
        DMPS_DB_TYPE_PSD, &serdes_num, physic_serdes));

    if (MCHIP_DMPS(lchip)->psd_to_serdes)
    {
        CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->psd_to_serdes(lchip, physic_serdes[0], &serdes_id));
    }
    else
    {
        serdes_id = physic_serdes[0];
    }

    p_value->serdes_id   = serdes_id;
    p_value->serdes_mode = if_mode;
    p_value->serdes_num  = serdes_num;
    p_value->overclocking_speed = ocs_mode;

    for(idx = 0; idx < p_value->serdes_num; idx++)
    {
        if (MCHIP_DMPS(lchip)->psd_to_serdes)
        {
            CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->psd_to_serdes(lchip, physic_serdes[idx], &serdes_id));
        }
        else
        {
            serdes_id = physic_serdes[idx];
        }

        p_value->serdes_id_array[idx] = serdes_id;
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_speed_mode_capability(uint8 lchip, uint16 dport, uint32* speed_mode_bitmap)
{
    uint32 tmp_bitmap = 0;

    tmp_bitmap |= (1 << CTC_PORT_SPEED_1G);
    tmp_bitmap |= (1 << CTC_PORT_SPEED_2G5);
    tmp_bitmap |= (1 << CTC_PORT_SPEED_10G);
    tmp_bitmap |= (1 << CTC_PORT_SPEED_40G);
    tmp_bitmap |= (1 << CTC_PORT_SPEED_100G);
    tmp_bitmap |= (1 << CTC_PORT_SPEED_25G);
    tmp_bitmap |= (1 << CTC_PORT_SPEED_50G);

    *speed_mode_bitmap = tmp_bitmap;

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_if_type_capability(uint8 lchip, uint16 dport, uint32* if_type_bitmap)
{
    uint32 tmp_if_type_bitmap = 0;

    tmp_if_type_bitmap |= (1 << CTC_PORT_IF_XFI);
    tmp_if_type_bitmap |= (1 << CTC_PORT_IF_KR);
    tmp_if_type_bitmap |= (1 << CTC_PORT_IF_CR);
    tmp_if_type_bitmap |= (1 << CTC_PORT_IF_KR2);
    tmp_if_type_bitmap |= (1 << CTC_PORT_IF_CR2);
    tmp_if_type_bitmap |= (1 << CTC_PORT_IF_KR4);
    tmp_if_type_bitmap |= (1 << CTC_PORT_IF_CR4);

    tmp_if_type_bitmap |= (1 << CTC_PORT_IF_SGMII);
    tmp_if_type_bitmap |= (1 << CTC_PORT_IF_2500X);

    *if_type_bitmap = tmp_if_type_bitmap;

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_fec_type_capability(uint8 lchip, uint16 dport, uint32* p_value)
{
    uint8  if_mode  = 0;
    sys_dmps_db_upt_info_t port_info = {0};
    CTC_PTR_VALID_CHECK(p_value);

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,             dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);

    switch(if_mode)
    {
        case CTC_CHIP_SERDES_XXVG_MODE:
            *p_value = (1 << CTC_PORT_FEC_TYPE_RS528);
            *p_value |= (1 << CTC_PORT_FEC_TYPE_FC2112);
            break;
            
        case CTC_CHIP_SERDES_LG_MODE:
            *p_value = (1 << CTC_PORT_FEC_TYPE_RS528);
            break;
        case CTC_CHIP_SERDES_CG_MODE:
            *p_value = (1 << CTC_PORT_FEC_TYPE_RS528);
            break;
        case CTC_CHIP_SERDES_XFI_MODE:
        case CTC_CHIP_SERDES_XLG_MODE:
            *p_value = (1 << CTC_PORT_FEC_TYPE_FC2112);
            break;
        default:
            *p_value = (1 << CTC_PORT_FEC_TYPE_NONE);
            break;
    }
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_capability(uint8 lchip, uint16 lport, ctc_port_capability_type_t type, void* p_value)
{
    uint16 dport  = 0;
    uint16 mac_id = 0;
    
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get port capability, lport:%u, type:%d!\n", lport, type);

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    switch(type)
    {
        case CTC_PORT_CAP_TYPE_SERDES_INFO:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_serdes_info_capability(lchip, dport,
                (ctc_port_serdes_info_t*)p_value));
            break;
        case CTC_PORT_CAP_TYPE_SPEED_MODE:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_speed_mode_capability(lchip, dport, (uint32*)p_value));
            break;
        case CTC_PORT_CAP_TYPE_IF_TYPE:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_if_type_capability(lchip, dport, (uint32*)p_value));
            break;
        case CTC_PORT_CAP_TYPE_FEC_TYPE:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_fec_type_capability(lchip, dport, (uint32*)p_value));
            break;       
        case CTC_PORT_CAP_TYPE_MAC_ID:
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_dport_relative_id(lchip, dport, DMPS_DB_TYPE_MAC, &mac_id));
            *(uint32*)p_value = (uint32)mac_id;
            break;
        case CTC_PORT_CAP_TYPE_LOCAL_PAUSE_ABILITY:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_cl37_flowctl_ability_local(lchip, dport, (uint32*)p_value));
            break;
        case CTC_PORT_CAP_TYPE_REMOTE_PAUSE_ABILITY:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_cl37_flowctl_ability_remote(lchip, dport, (uint32*)p_value));
            break;
        case CTC_PORT_CAP_TYPE_CL73_ABILITY:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_cl73_capability(lchip, dport, (uint32*)p_value));
            break;
        case CTC_PORT_CAP_TYPE_CL73_REMOTE_ABILITY:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_cl73_ability(lchip, dport, 1, (uint32*)p_value));
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }
    
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_ipg(uint8 lchip, uint16 dport, uint32 value_raw)
{
    uint32 value        = value_raw & 0x000000ff;
    uint32 cfg_en       = (value_raw >> 8) & 0x000000ff;
    uint32 tbl_id       = 0;
    uint32 fld_id       = 0;
    uint32 index        = 0;
    uint32 cmd          = 0;

    SharedMii0Cfg_m      mii_cfg;
    QuadSgmacStatsCfg_m  stats_cfg;
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, value %u\n", __FUNCTION__, lchip, dport, value);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_IPG, lchip, &api_db, value);

    /* #1, calc index */
    index = DRV_INS(api_db.mac_grp_idx, 0);
    /* #2, read HW table */
    dmps_SharedMii0Cfg_t(api_db.mac_idx, tbl_id);
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mii_cfg));
    /* #3. write field value */
    DRV_IOW_FIELD_NZ(lchip, tbl_id, SharedMii0Cfg_cfgMiiTxModEn0_f, &cfg_en, &mii_cfg, api_db.mac_grp_idx, 0);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, SharedMii0Cfg_cfgMiiRxModEn0_f, &cfg_en, &mii_cfg, api_db.mac_grp_idx, 0);
    /* #4. write HW table */
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mii_cfg));
    
    /* #1, calc index */
    index = DRV_INS(api_db.mac_grp_idx, 0);
    /* #2, read HW table */
    tbl_id = QuadSgmacStatsCfg_t;
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &stats_cfg));
    /* #3. write field value */
    dmps_QuadSgmacStatsCfg_cfgSgmac0RxMod_f(api_db.mac_idx, fld_id);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &cfg_en, &stats_cfg, api_db.mac_grp_idx, 0);
    dmps_QuadSgmacStatsCfg_cfgSgmac0TxMod_f(api_db.mac_idx, fld_id);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &cfg_en, &stats_cfg, api_db.mac_grp_idx, 0);
    
    /* #4. write HW table */
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &stats_cfg));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_ipg(uint8 lchip, uint16 dport, uint32* p_value)
{
    uint16 lport        = 0;
    uint32 tbl_id       = 0;
    uint32 index        = 0;
    uint32 cmd          = 0;
    uint32 value        = 0;
    
    SharedMii0Cfg_m mii_cfg;
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_PTR_VALID_CHECK(p_value);
    
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u\n", __FUNCTION__, lchip, dport);

    CTC_ERROR_RETURN(sys_usw_dmps_db_dport_2_lport(lchip, dport, &lport));
    if (CTC_E_NONE == sys_usw_phy_get_phy_register_exist(lchip, lport))
    {
        CTC_ERROR_RETURN(sys_usw_phy_get_phy_property(lchip, lport, CTC_PORT_PROP_UNIDIR_EN, (void*)(&value)));
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_IPG, lchip, &api_db, p_value);
    
    /* #1, calc index */
    index = DRV_INS(api_db.mac_grp_idx, 0);
    /* #2, read HW table */
    dmps_SharedMii0Cfg_t(api_db.mac_idx, tbl_id);
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mii_cfg));
    /* #3. read field value */
    DRV_IOR_FIELD(lchip, tbl_id, SharedMii0Cfg_cfgMiiTxModEn0_f, &value, &mii_cfg);

    *p_value = *p_value | value << 8;
   
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_frame_property(uint8 lchip, uint16 dport, ctc_port_property_t port_prop, uint32 value)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, port_prop %u, value %u\n", __FUNCTION__, lchip, dport, port_prop, value);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    switch(port_prop)
    {
        case CTC_PORT_PROP_PREAMBLE:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_PREAMBLE, lchip, &api_db, value);
            break;
        case CTC_PORT_PROP_PADING_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_PADDING_EN, lchip, &api_db, value);
            break;
        case CTC_PORT_PROP_CHK_CRC_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_CHECK_CRC_EN, lchip, &api_db, value);
            break;
        case CTC_PORT_PROP_STRIP_CRC_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_STRIP_CRC_EN, lchip, &api_db, value);
            break;
        case CTC_PORT_PROP_APPEND_CRC_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_APPEND_CRC_EN, lchip, &api_db, value);
            break;
        case CTC_PORT_PROP_APPEND_TOD_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_APPEND_TOD_EN, lchip, &api_db, value);
            break;
        case CTC_PORT_PROP_MAC_TS_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_TAILTS_EN, lchip, &api_db, value);
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_frame_property(uint8 lchip, uint16 dport, ctc_port_property_t port_prop, uint32 *p_value)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, port_prop %u\n", __FUNCTION__, lchip, dport, port_prop);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    switch(port_prop)
    {
        case CTC_PORT_PROP_PREAMBLE:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_PREAMBLE, lchip, &api_db, p_value);
            break;
        case CTC_PORT_PROP_PADING_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_PADDING_EN, lchip, &api_db, p_value);
            break;
        case CTC_PORT_PROP_CHK_CRC_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_CHECK_CRC_EN, lchip, &api_db, p_value);
            break;
        case CTC_PORT_PROP_STRIP_CRC_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_STRIP_CRC_EN, lchip, &api_db, p_value);
            break;
        case CTC_PORT_PROP_APPEND_CRC_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_APPEND_CRC_EN, lchip, &api_db, p_value);
            break;
        case CTC_PORT_PROP_APPEND_TOD_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_APPEND_TOD_EN, lchip, &api_db, p_value);
            break;
        case CTC_PORT_PROP_MAC_TS_EN:
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_TAILTS_EN, lchip, &api_db, p_value);
            break;
        default:
            break;
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_sfd_en(uint8 lchip, uint16 lport, uint32 enable)
{
    uint16 dport                = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, value %u\n", __FUNCTION__, lchip, dport, enable);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_SFD_EN, lchip, &api_db, (enable?0x5d:0xd5));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_sfd_en(uint8 lchip, uint16 lport, uint32* p_enable)
{
    uint16 dport                = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    uint32 value                = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_SFD_EN, lchip, &api_db, &value);
    *p_enable = (0x5d == value) ? 1 : 0;

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_tailts_en(uint8 lchip, uint16 dport, uint32 value)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"dport:%d, enable:0x%X\n", dport, value);

    SYS_MAC_INIT_CHECK();

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    /*valid config : 0b00 0b10 0b11    bit 1 ~ en  bit 0 ~ mode*/
    if((0 != value) && (2 != value) && (3 != value))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Invalid config %u!\n", value);
        return CTC_E_INVALID_PARAM;
    }

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_TAILTS_EN, lchip, &api_db, value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_tailts_en(uint8 lchip, uint16 dport, uint32* p_value)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u\n", __FUNCTION__, lchip, dport);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_TAILTS_EN, lchip, &api_db, p_value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_internal_property(uint8 lchip, uint16 lport, ctc_port_property_t port_prop, uint32 value)
{
    uint16 dport = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    uint8  enable = (value) ? TRUE : FALSE;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set port property, lport:0x%04X, property:%d, value:%d\n", lport, port_prop, value);

    SYS_CONDITION_RETURN(FALSE == sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, dport), CTC_E_INVALID_PARAM);

    switch(port_prop)
    {
        case CTC_PORT_PROP_CL73_ABILITY:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_cl73_ability(lchip, dport, value));
            break;
        case CTC_PORT_PROP_LINK_INTRRUPT_EN:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_link_intr(lchip, dport, enable));
            break;
        case CTC_PORT_PROP_UNIDIR_EN:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_unidir_en(lchip, dport, value));
            break;
        case CTC_PORT_PROP_MAC_TX_IPG:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_ipg(lchip, dport, value));
            break;
        case CTC_PORT_PROP_PREAMBLE:
        case CTC_PORT_PROP_PADING_EN:
        case CTC_PORT_PROP_CHK_CRC_EN:
        case CTC_PORT_PROP_STRIP_CRC_EN:
        case CTC_PORT_PROP_APPEND_CRC_EN:
        case CTC_PORT_PROP_APPEND_TOD_EN:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_frame_property(lchip, dport, port_prop, value));
            break;
        case CTC_PORT_PROP_XPIPE_MODE:
            break;
        case CTC_PORT_PROP_MAC_TS_EN:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_tailts_en(lchip, dport, value));
            break;
        case CTC_PORT_PROP_PAR_DET_EN:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_parallel_detect_en(lchip, dport, value));
            break;
        case CTC_PORT_PROP_ERROR_CHECK:
        case CTC_PORT_PROP_RX_PAUSE_TYPE:
        case CTC_PORT_PROP_LINKSCAN_EN:
            if(0 == value)
            {
                CTC_ERROR_RETURN(_sys_usw_dmps_set_daemon_en(lchip, 0));
            }
            else
            {
                CTC_ERROR_RETURN(_sys_usw_dmps_set_daemon_en(lchip, 1));
                CTC_ERROR_RETURN(_sys_usw_dmps_set_daemon_gap_ms(lchip, value));
            }
            break;
        default:
            return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_internal_property(uint8 lchip, uint16 lport, ctc_port_property_t port_prop, uint32* p_value)
{
    uint32 tmp_val = 0;
    uint16 dport = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get port property, lport:0x%04X, property:%d!\n", lport, port_prop);

    SYS_CONDITION_RETURN(FALSE == sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, dport), CTC_E_INVALID_PARAM);

    switch(port_prop)
    {
        case CTC_PORT_PROP_CL73_ABILITY:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_cl73_ability(lchip, dport, 0, p_value));
            break;
        case CTC_PORT_PROP_LINK_INTRRUPT_EN:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_link_intr(lchip, dport, p_value));
            break;
        case CTC_PORT_PROP_PREAMBLE:
        case CTC_PORT_PROP_PADING_EN:
        case CTC_PORT_PROP_CHK_CRC_EN:
        case CTC_PORT_PROP_STRIP_CRC_EN:
        case CTC_PORT_PROP_APPEND_CRC_EN:
        case CTC_PORT_PROP_APPEND_TOD_EN:
        case CTC_PORT_PROP_MAC_TS_EN:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_frame_property(lchip, dport, port_prop, p_value));
            break;
        case CTC_PORT_PROP_UNIDIR_EN:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_unidir_en(lchip, dport, p_value));
            break;
        case CTC_PORT_PROP_MAC_TX_IPG:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_ipg(lchip, dport, p_value));
            break;
        case CTC_PORT_PROP_XPIPE_MODE:
            break;
        case CTC_PORT_PROP_PAR_DET_EN:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_parallel_detect_en(lchip, dport, p_value));
            break;
        case CTC_PORT_PROP_FEC_CNT:
            CTC_ERROR_RETURN(_sys_tmg_mac_get_fec_cnt(lchip, dport, p_value));
            break;
        case CTC_PORT_PROP_ERROR_CHECK:
        case CTC_PORT_PROP_RX_PAUSE_TYPE:
        case CTC_PORT_PROP_LINKSCAN_EN:
            CTC_ERROR_RETURN(_sys_usw_dmps_get_daemon_en(lchip, &tmp_val));
            if(tmp_val)
            {
                CTC_ERROR_RETURN(_sys_usw_dmps_get_daemon_gap_ms(lchip, p_value));
            }
            else
            {
                *p_value = 0;
            }
            break;
        default:
            return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_init_pulse_cfg(uint8 lchip)
{

uint32 val_hb  = 1250;

#ifdef EMULATION_ENV
    uint32 val_flt = 1000;
#else
    uint32 val_flt = 0x003d0900; /*100us per cycle, 0.1ms*/
#endif
    uint32 cmd = 0;
    RefDivMcPcsLinkPulse_m rd_pcs;
    RefDivMcMacPulse_m     rd_mac;
    RefDivCpuMacPulse_m    rd_cpumac;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    DP_DEBUG_FUNCTION_CALLED_PRINT();
#ifdef TMG_SERDES_SIM
    g_print_tbl = FALSE;
#endif

    /* Enlarge link Filter */
    cmd = DRV_IOR(RefDivMcPcsLinkPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_pcs));
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac0Dp0McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac0Dp1McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac1Dp0McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac1Dp1McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac2Dp0McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac2Dp1McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac3Dp0McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac3Dp1McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac4Dp0McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgRefDivMcMac4Dp1McPcsLinkPulse_f, &val_flt, &rd_pcs, 0, 0);
    cmd = DRV_IOW(RefDivMcPcsLinkPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_pcs));

    cmd = DRV_IOR(RefDivMcMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_mac));
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac0Dp0LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac0Dp1LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac1Dp0LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac1Dp1LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac2Dp0LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac2Dp1LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac3Dp0LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac3Dp1LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac4Dp0LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac4Dp1LinkFilterPulse_f, &val_flt, &rd_mac, 0, 0);

    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac0Dp0HiBerPulse_f, &val_hb, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac0Dp1HiBerPulse_f, &val_hb, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac1Dp0HiBerPulse_f, &val_hb, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac1Dp1HiBerPulse_f, &val_hb, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac2Dp0HiBerPulse_f, &val_hb, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac2Dp1HiBerPulse_f, &val_hb, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac3Dp0HiBerPulse_f, &val_hb, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac3Dp1HiBerPulse_f, &val_hb, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac4Dp0HiBerPulse_f, &val_hb, &rd_mac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac4Dp1HiBerPulse_f, &val_hb, &rd_mac, 0, 0);

    cmd = DRV_IOW(RefDivMcMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_mac));

    cmd = DRV_IOR(RefDivCpuMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_cpumac));
    DRV_IOW_FIELD_NZ(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgRefDivCpuMacLinkPulse_f,       &val_flt, &rd_cpumac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgRefDivCpuMacHiBerPulse_f,       &val_hb, &rd_cpumac, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgRefDivCpuMacLinkFilterPulse_f, &val_flt, &rd_cpumac, 0, 0);

    cmd = DRV_IOW(RefDivCpuMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_cpumac));

#ifdef TMG_SERDES_SIM
    g_print_tbl = TRUE;
#endif

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_sgmii_config(uint8 lchip, uint16 mac_id)
{
    uint8  qmac_id                      = 0;
    uint8  lr_flag                      = 0; /*0~left 1~right*/
    uint8  mac_grp                      = 0;
    uint32 val_wid                      = 0;
    uint32 val_cnt                      = 0;
    uint32 val_afu                      = 0;
    uint32 val_spd                      = 0;
    uint32 val_mux                      = 0;
    uint32 val_rbm                      = 0;
    uint32 val_tbm                      = 0;
    uint32 cmd                          = 0;
    uint32 tbl_id                       = 0;
    uint32 index                        = 0;
    uint8  psd_num                      = 0;
    uint16 spd_mod                      = 0;
    uint16 dport                        = 0;
    uint16 psd[DMPS_MAX_NUM_PER_MODULE] = {0};
    SharedMiiCfg_m          mii_cfg;
    QuadSgmacCfg_m          qmc_cfg;
    sys_dmps_mac_api_db_t   api_db      = {0};
    sys_dmps_db_upt_info_t  port_info   = {0};
    sys_dmps_api_cfg_t      cfg_list[SYS_DMPS_SHARED_API_CFG_MAX] = {{0}};


    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_MAC, mac_id, DMPS_DB_TYPE_PORT, NULL, &dport));
    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));
    spd_mod = api_db.speed_mode;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, mac %u, if_mode %u\n", __FUNCTION__, lchip, mac_id, api_db.if_mode);
    
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_PSD, &psd_num, psd));
    qmac_id = SYS_TMG_GET_QUAD_MAC_ID(port_info.mac_id);
    lr_flag = (2 > qmac_id) ? 0 : 1;
    mac_grp = port_info.mac_group;
    index = DRV_INS(mac_grp, 0);
    tbl_id = QuadSgmacCfg_t;
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &qmc_cfg));
    DRV_IOR_FIELD(lchip, tbl_id, QuadSgmacCfg_cfgQuadSgmacRxBufMode_f, &val_rbm, &qmc_cfg);
    DRV_IOR_FIELD(lchip, tbl_id, QuadSgmacCfg_cfgQuadSgmacTxBufMode_f, &val_tbm, &qmc_cfg);

    index = DRV_INS(mac_grp, 0);
    tbl_id = SharedMiiCfg_t;
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mii_cfg));
    DRV_IOR_FIELD(lchip, tbl_id, SharedMiiCfg_cfgSharedMiiMuxMode_f, &val_mux, &mii_cfg);

    if(lr_flag)
    {
        val_rbm &= 0xfffffffd;
        val_tbm &= 0xfffffffd;
        val_mux &= 0xfffffffd;
    }
    else
    {
        val_rbm &= 0xfffffffe;
        val_tbm &= 0xfffffffe;
        val_mux &= 0xfffffffe;
    }

    switch(spd_mod)
    {
        case CTC_PORT_SPEED_2G5:
            val_spd = 3;
            val_cnt = 0;
            val_afu = 11;
            break;
        case CTC_PORT_SPEED_1G:
            val_spd = 2;
            val_cnt = 0;
            val_afu = 4;
            break;
        case CTC_PORT_SPEED_100M:
            val_spd = 1;
            val_cnt = 9;
            val_afu = 11;
            break;
        case CTC_PORT_SPEED_10M:
            val_spd = 0;
            val_cnt = 99;
            val_afu = 11;
            break;
        default:
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"error port speed mode: %d \n", spd_mod);
            return CTC_E_INVALID_PARAM;
    }

    switch(qmac_id)
    {
        case 0:
            val_wid = 2;
            break;
        case 2:
            val_wid = 1;
            break;
        default:
            val_wid = 0;
            break;
    }

    index = DRV_INS(mac_grp, 0);
    tbl_id = SharedMiiCfg_t;
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mii_cfg));
    DRV_IOR_FIELD(lchip, tbl_id, SharedMiiCfg_cfgSharedMiiMuxMode_f, &val_mux, &mii_cfg);
    val_mux &= (~((uint32)(qmac_id < 2 ? 1 : 2)));

    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[QUAD_SGMAC_RX_BUF_MODE],            val_rbm);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[QUAD_SGMAC_TX_BUF_MODE],            val_tbm);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_OUTPUT_WIDTH],            3);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_KEEP_TS_EN],              0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_RX_INPUT_WIDTH],             val_wid);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_WAIT_CAPTURE_TS],         1);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_PACE_DEC_VALUE],     1);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_PACE_INC_VALUE],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_SPEED_RX],              val_spd);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_RS_FEC_EN],          0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_FX_MODE],               0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_RX_SAMPLE_SLOT],        0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_RX_SAMPLE_CNT],         val_cnt);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_REPLICATE_SLOT],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_REPLICATE_CNT],      val_cnt);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_AFULL_THRD],         val_afu);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_USXGMII_EN],            0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_SPEED],                 val_spd);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_AM_INTERVAL],        16383);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII_TX_IPG_DEL_INTERVAL],    1);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII_MUX_MODE],               val_mux);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_CG_MODE],                0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XLG_MODE],               0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE0+qmac_id],       0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_LG_MODE0+qmac_id/2],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE0+qmac_id],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX0+qmac_id], 1);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX0+qmac_id], 1);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR0+qmac_id],        0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SERDES_RX_POP_CNT],      80);

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MODE, lchip, &api_db, cfg_list);

    CTC_ERROR_RETURN(sys_tmg_serdes_set_hss_clktree_cfg(lchip, mac_grp, psd_num, psd, api_db.if_mode));
    
    CTC_ERROR_RETURN(sys_tmg_serdes_set_trx_dataout_sel(lchip, mac_grp, psd_num, psd, api_db.if_mode));

    return CTC_E_NONE;
}


int32
_sys_tmg_mac_set_xfi_xxvg_config(uint8 lchip, uint16 mac_id)
{
    uint8  qmac_id                      = 0;
    uint8  lr_flag                      = 0; /*0~left 1~right*/
    uint8  mac_grp                      = 0;
    uint32 val_wid                      = 0;
    uint32 val_dec                      = 0;
    uint32 val_inc                      = 0;
    uint32 val_spd                      = 0;
    uint32 val_mux                      = 0;
    uint32 val_mod                      = 0;
    uint32 val_rbm                      = 0;
    uint32 val_tbm                      = 0;
    uint32 cmd                          = 0;
    uint32 tbl_id                       = 0;
    uint32 index                        = 0;
    uint8  psd_num                      = 0;
    uint16 serdes_speed                 = 0;
    uint16 if_mode                      = 0;
    uint16 fec_type                     = 0;
    uint8  mii_idx                      = 0;
    uint16 lsd[DMPS_MAX_NUM_PER_MODULE] = {0};
    uint16 psd[DMPS_MAX_NUM_PER_MODULE] = {0};
    SharedMiiCfg_m          mii_cfg;
    QuadSgmacCfg_m          qmc_cfg;
    sys_dmps_mac_api_db_t   api_db      = {0};
    sys_dmps_db_upt_info_t  port_info   = {0};
    sys_dmps_api_cfg_t      cfg_list[SYS_DMPS_SHARED_API_CFG_MAX] = {{0}};

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PSD_SPEED);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_GROUP_ID);   
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_IDX);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PSD_SPEED, serdes_speed);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_GROUP_ID, mac_grp);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_IDX, mii_idx);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_MAC, mac_id, DMPS_DB_TYPE_PSD, &psd_num, psd));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_MAC, mac_id, DMPS_DB_TYPE_LSD, NULL, lsd));

    if(0 == serdes_speed)
    {
        if_mode     = CTC_CHIP_SERDES_XFI_MODE;
        fec_type    = SYS_DMPS_FEC_TYPE_NONE;
    }
    else
    {
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE,  if_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_FEC_TYPE, fec_type);
    }

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, if_mode %u\n", __FUNCTION__, lchip, mac_id, if_mode);

    api_db.core_id  = 0;
    api_db.fec_type = fec_type;
    api_db.if_mode  = if_mode;
    api_db.mac_grp_idx = mac_grp;
    api_db.mac_idx     = mii_idx;
    api_db.pcs_grp_idx = mac_grp;
    api_db.pcs_idx     = SYS_TMG_GET_INNER_LANE_BY_SERDES(lsd[0]);
    
    qmac_id = SYS_TMG_GET_QUAD_MAC_ID(mac_id);
    lr_flag = (2 > qmac_id) ? 0 : 1;
    index = DRV_INS(mac_grp, 0);
    tbl_id = QuadSgmacCfg_t;
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &qmc_cfg));
    DRV_IOR_FIELD(lchip, tbl_id, QuadSgmacCfg_cfgQuadSgmacRxBufMode_f, &val_rbm, &qmc_cfg);
    DRV_IOR_FIELD(lchip, tbl_id, QuadSgmacCfg_cfgQuadSgmacTxBufMode_f, &val_tbm, &qmc_cfg);

    index = DRV_INS(mac_grp, 0);
    tbl_id = SharedMiiCfg_t;
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mii_cfg));
    DRV_IOR_FIELD(lchip, tbl_id, SharedMiiCfg_cfgSharedMiiMuxMode_f, &val_mux, &mii_cfg);

    if(lr_flag)
    {
        val_rbm &= 0xfffffffd;
        val_tbm &= 0xfffffffd;
        val_mux &= 0xfffffffd;
    }
    else
    {
        val_rbm &= 0xfffffffe;
        val_tbm &= 0xfffffffe;
        val_mux &= 0xfffffffe;
    }

    if(if_mode == CTC_CHIP_SERDES_XXVG_MODE)
    {
        val_spd = 7;
        val_dec = 32;
        val_inc = 1;
        val_mod = 1;
    }
    else
    {
        val_spd = 5;
        val_dec = 16;
        val_inc = 17;
        val_mod = 0;
    }
    switch(qmac_id)
    {
        case 0:
            val_wid = 2;
            break;
        case 2:
            val_wid = 1;
            break;
        default:
            val_wid = 0;
            break;
    }

    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[QUAD_SGMAC_RX_BUF_MODE],            val_rbm);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[QUAD_SGMAC_TX_BUF_MODE],            val_tbm);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_OUTPUT_WIDTH],            val_wid);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_RX_INPUT_WIDTH],             val_wid);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_KEEP_TS_EN],              0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_WAIT_CAPTURE_TS],         0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_PACE_DEC_VALUE],     val_dec);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_PACE_INC_VALUE],     val_inc);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_SPEED_RX],              val_spd);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_RS_FEC_EN],          0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_FX_MODE],               0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_RX_SAMPLE_SLOT],        0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_RX_SAMPLE_CNT],         0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_REPLICATE_SLOT],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_REPLICATE_CNT],      0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_AFULL_THRD],         11);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_USXGMII_EN],            0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_SPEED],                 val_spd);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_AM_INTERVAL],        16383);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII_TX_IPG_DEL_INTERVAL],    1);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII_MUX_MODE],               val_mux);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_CG_MODE],                0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XLG_MODE],               0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE0+qmac_id],       0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_LG_MODE0+qmac_id/2],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE0+qmac_id],     val_mod);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX0+qmac_id], 0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX0+qmac_id], 0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR0+qmac_id],        0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SERDES_RX_POP_CNT],      100);

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MODE, lchip, &api_db, cfg_list);

    CTC_ERROR_RETURN(sys_tmg_serdes_set_hss_clktree_cfg(lchip, mac_grp, psd_num, psd, if_mode));
    
    CTC_ERROR_RETURN(sys_tmg_serdes_set_trx_dataout_sel(lchip, mac_grp, psd_num, psd, if_mode));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_xlg_cg_config(uint8 lchip, uint16 mac_id)
{
    uint8  mac_grp                      = 0;
    uint32 val_wid                      = 0;
    uint32 val_ipg                      = 0;
    uint32 val_dec                      = 0;
    uint32 val_inc                      = 0;
    uint32 val_spd                      = 0;
    uint32 val_pop                      = 0;
    uint32 val_mcg                      = 0;
    uint32 val_mxl                      = 0;
    uint8  psd_num                      = 0;
    uint16 psd[DMPS_MAX_NUM_PER_MODULE] = {0};
    uint16 dport                        = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};
    sys_dmps_db_upt_info_t  port_info   = {0};
    sys_dmps_api_cfg_t      cfg_list[SYS_DMPS_SHARED_API_CFG_MAX] = {{0}};

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_MAC, mac_id, DMPS_DB_TYPE_PORT, NULL, &dport));
    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, if_mode %u\n", __FUNCTION__, lchip, dport, api_db.if_mode);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_PSD, &psd_num, psd));

    mac_grp = api_db.mac_grp_idx;

    if(api_db.if_mode == CTC_CHIP_SERDES_CG_MODE)
    {
        val_wid = 0;
        val_ipg = 0;
        val_dec = 32;
        val_inc = 1;
        val_spd = 10;
        val_pop = 100;
        val_mcg = 1;
        val_mxl = 0;
    }
    else
    {
        val_wid = 1;
        val_ipg = 1;
        val_dec = 16;
        val_inc = 17;
        val_spd = 8;
        val_pop = 80;
        val_mcg = 0;
        val_mxl = 1;
    }

    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[QUAD_SGMAC_RX_BUF_MODE],        2);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[QUAD_SGMAC_TX_BUF_MODE],        2);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_OUTPUT_WIDTH],        val_wid);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_RX_INPUT_WIDTH],         val_wid);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_KEEP_TS_EN],              0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_WAIT_CAPTURE_TS],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_PACE_DEC_VALUE], val_dec);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_PACE_INC_VALUE], val_inc);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_SPEED_RX],          val_spd);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_RS_FEC_EN],      0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_FX_MODE],           0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_RX_SAMPLE_SLOT],    0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_RX_SAMPLE_CNT],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_REPLICATE_SLOT], 0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_REPLICATE_CNT],  0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_AFULL_THRD],     11);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_USXGMII_EN],        0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_SPEED],             val_spd);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_AM_INTERVAL],    16383);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII_TX_IPG_DEL_INTERVAL],val_ipg);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII_MUX_MODE],           2);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_CG_MODE],            val_mcg);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XLG_MODE],           val_mxl);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE0],           0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE1],           0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE2],           0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE3],           0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_LG_MODE0],           0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_LG_MODE1],           0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE0],         0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE1],         0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE2],         0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE3],         0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX0],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX1],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX2],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX3],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX0],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX1],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX2],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX3],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR0],            0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR1],            0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR2],            0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR3],            0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SERDES_RX_POP_CNT],  val_pop);

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MODE, lchip, &api_db, cfg_list);

    CTC_ERROR_RETURN(sys_tmg_serdes_set_hss_clktree_cfg(lchip, mac_grp, psd_num, psd, api_db.if_mode));

    CTC_ERROR_RETURN(sys_tmg_serdes_set_trx_dataout_sel(lchip, mac_grp, psd_num, psd, api_db.if_mode));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_lg_config(uint8 lchip, uint16 mac_id)
{
    uint8  mac_grp                      = 0;
    uint8  lr_flag                      = 0; /*0~left 1~right*/
    uint32 val_rbm                      = 0;
    uint32 val_tbm                      = 0;
    uint32 val_mux                      = 0;
    uint32 val_wid                      = 0;
    uint32 cmd                          = 0;
    uint32 tbl_id                       = 0;
    uint32 index                        = 0;
    uint8  psd_num                      = 0;
    uint16 dport                        = 0;
    uint16 psd[DMPS_MAX_NUM_PER_MODULE] = {0};
    QuadSgmacCfg_m          qmc_cfg;
    SharedMiiCfg_m          mii_cfg;
    sys_dmps_mac_api_db_t   api_db      = {0};
    sys_dmps_db_upt_info_t  port_info   = {0};
    sys_dmps_api_cfg_t      cfg_list[SYS_DMPS_SHARED_API_CFG_MAX] = {{0}};

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_MAC, mac_id, DMPS_DB_TYPE_PORT, NULL, &dport));
    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, if_mode %u\n", __FUNCTION__, lchip, dport, api_db.if_mode);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_PSD, &psd_num, psd));
    lr_flag = (2 > SYS_TMG_GET_QUAD_MAC_ID(port_info.mac_id)) ? 0 : 1;
    mac_grp = api_db.mac_grp_idx;
    index = DRV_INS(mac_grp, 0);
    tbl_id = QuadSgmacCfg_t;
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &qmc_cfg));
    DRV_IOR_FIELD(lchip, tbl_id, QuadSgmacCfg_cfgQuadSgmacRxBufMode_f, &val_rbm, &qmc_cfg);
    DRV_IOR_FIELD(lchip, tbl_id, QuadSgmacCfg_cfgQuadSgmacTxBufMode_f, &val_tbm, &qmc_cfg);

    tbl_id = SharedMiiCfg_t;
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mii_cfg));
    DRV_IOR_FIELD(lchip, tbl_id, SharedMiiCfg_cfgSharedMiiMuxMode_f, &val_mux, &mii_cfg);

    if(lr_flag)
    {
        /*QuadSgmacCfg_cfgQuadSgmacRxBufMode*/
        val_rbm |= 0x6;
        /*QuadSgmacCfg_cfgQuadSgmacTxBufMode*/
        val_tbm |= 0x6;
        /*Sgmac0RxCfg_cfgSgmac0RxInputWidth*/
        /*Sgmac0TxCfg_cfgSgmac0TxOutputWidth*/
        val_wid = 0;
        /*SharedMiiCfg_cfgSharedMiiMuxMode*/
        val_mux |= 0x6;
    }
    else
    {
        /*QuadSgmacCfg_cfgQuadSgmacRxBufMode*/
        val_rbm |= 0x5;
        /*QuadSgmacCfg_cfgQuadSgmacTxBufMode*/
        val_tbm |= 0x5;
        /*Sgmac0RxCfg_cfgSgmac0RxInputWidth*/
        /*Sgmac0TxCfg_cfgSgmac0TxOutputWidth*/
        val_wid = 1;
        /*SharedMiiCfg_cfgSharedMiiMuxMode*/
        val_mux |= 0x5;
    }

    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[QUAD_SGMAC_RX_BUF_MODE],        val_rbm);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[QUAD_SGMAC_TX_BUF_MODE],        val_tbm);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_OUTPUT_WIDTH],        val_wid);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_RX_INPUT_WIDTH],         val_wid);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_KEEP_TS_EN],              0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SGMAC0_TX_WAIT_CAPTURE_TS],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_PACE_DEC_VALUE], 16);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_PACE_INC_VALUE], 17);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_SPEED_RX],          9);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_RS_FEC_EN],      0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_FX_MODE],           0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_RX_SAMPLE_SLOT],    0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_RX_SAMPLE_CNT],     0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_REPLICATE_SLOT], 0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_REPLICATE_CNT],  0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_AFULL_THRD],     11);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_USXGMII_EN],        0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_SPEED],             9);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII0_TX_AM_INTERVAL],    16383);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII_TX_IPG_DEL_INTERVAL],1);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_MII_MUX_MODE],           val_mux);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_CG_MODE],            0);
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XLG_MODE],           0);
    if(lr_flag)
    {
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE2],       0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE3],       0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_LG_MODE1],       1);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE2],     0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE3],     0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX2], 0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX3], 0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX2], 0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX3], 0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR2],        0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR3],        0);
    }
    else
    {
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE0],       0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_FX_MODE1],       0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_LG_MODE0],       1);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE0],     0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_XXVG_MODE1],     0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX0], 0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_TX1], 0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX0], 0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SGMII_MODE_RX1], 0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR0],        0);
        SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_UNIDIR1],        0);
    }
    SYS_DMPS_API_SET_FIELD_VALUE(cfg_list[SHARED_PCS_SERDES_RX_POP_CNT],  100);

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MODE, lchip, &api_db, cfg_list);

    CTC_ERROR_RETURN(sys_tmg_serdes_set_hss_clktree_cfg(lchip, mac_grp, psd_num, psd, api_db.if_mode));

    CTC_ERROR_RETURN(sys_tmg_serdes_set_trx_dataout_sel(lchip, mac_grp, psd_num, psd, api_db.if_mode));

    return CTC_E_NONE;
}

#if defined(EMULATION_ENV)
int32
_sys_tmg_mac_set_emu_pcslpbk_err_inj(uint8 lchip, uint32 lsd_rx, uint32 err_en, uint32 t_cycle, uint32 cycle_num, uint32 bit_num)
{
    uint32 cmd      = 0;
    uint32 txqm     = SYS_TMG_GET_TXQM_BY_MAC_ID(lsd_rx);
    uint32 lane     = SYS_TMG_GET_INNER_MAC_ID(lsd_rx);
    uint32 fld_en   = 0;
    uint32 fld_cs   = 0;
    uint32 fld_cn   = 0;
    uint32 fld_bn   = 0;
    PcsEmulLineLpbkCtl_m pcs_lpb;

    if((t_cycle > 655365) || (cycle_num > t_cycle) || (bit_num > 40))
    {
        return CTC_E_INVALID_CONFIG;
    }

    if(2 == txqm)
    {
        fld_en = PcsEmulLineLpbkCtl_cfgEmulErrInsertEnHss0Lane0_f + lane;
        fld_cs = PcsEmulLineLpbkCtl_cfgEmulErrInsertCyclesHss0Lane0_f + lane;
        fld_cn = PcsEmulLineLpbkCtl_cfgEmulErrInsertCntHss0Lane0_f + lane;
        fld_bn = PcsEmulLineLpbkCtl_cfgEmulErrInsertBitsHss0Lane0_f + lane;
    }
    else if(3 == txqm)
    {
        fld_en = PcsEmulLineLpbkCtl_cfgEmulErrInsertEnHss1Lane0_f + lane;
        fld_cs = PcsEmulLineLpbkCtl_cfgEmulErrInsertCyclesHss1Lane0_f + lane;
        fld_cn = PcsEmulLineLpbkCtl_cfgEmulErrInsertCntHss0Lane0_f + lane;
        fld_bn = PcsEmulLineLpbkCtl_cfgEmulErrInsertBitsHss0Lane0_f + lane;
    }
    else
    {
        return CTC_E_INTR_INVALID_PARAM;
    }
    
    cmd = DRV_IOR(PcsEmulLineLpbkCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &pcs_lpb));
    DRV_IOW_FIELD_NZ(lchip, PcsEmulLineLpbkCtl_t, fld_en, &err_en, &pcs_lpb, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, PcsEmulLineLpbkCtl_t, fld_cs, &t_cycle, &pcs_lpb, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, PcsEmulLineLpbkCtl_t, fld_cn, &cycle_num, &pcs_lpb, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, PcsEmulLineLpbkCtl_t, fld_bn, &bit_num, &pcs_lpb, 0, 0);
    cmd = DRV_IOW(PcsEmulLineLpbkCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &pcs_lpb));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_emu_pcslpbk_err_inj(uint8 lchip, uint32 lsd_rx, uint32* err_en, uint32* t_cycle, uint32* cycle_num, uint32* bit_num)
{
    uint32 cmd      = 0;
    uint32 txqm     = SYS_TMG_GET_TXQM_BY_MAC_ID(lsd_rx);
    uint32 lane     = SYS_TMG_GET_INNER_MAC_ID(lsd_rx);
    uint32 fld_en   = 0;
    uint32 fld_cs   = 0;
    uint32 fld_cn   = 0;
    uint32 fld_bn   = 0;
    PcsEmulLineLpbkCtl_m pcs_lpb;

    if(2 == txqm)
    {
        fld_en = PcsEmulLineLpbkCtl_cfgEmulErrInsertEnHss0Lane0_f + lane;
        fld_cs = PcsEmulLineLpbkCtl_cfgEmulErrInsertCyclesHss0Lane0_f + lane;
        fld_cn = PcsEmulLineLpbkCtl_cfgEmulErrInsertCntHss0Lane0_f + lane;
        fld_bn = PcsEmulLineLpbkCtl_cfgEmulErrInsertBitsHss0Lane0_f + lane;
    }
    else if(3 == txqm)
    {
        fld_en = PcsEmulLineLpbkCtl_cfgEmulErrInsertEnHss1Lane0_f + lane;
        fld_cs = PcsEmulLineLpbkCtl_cfgEmulErrInsertCyclesHss1Lane0_f + lane;
        fld_cn = PcsEmulLineLpbkCtl_cfgEmulErrInsertCntHss0Lane0_f + lane;
        fld_bn = PcsEmulLineLpbkCtl_cfgEmulErrInsertBitsHss0Lane0_f + lane;
    }
    else
    {
        return CTC_E_INTR_INVALID_PARAM;
    }
    
    cmd = DRV_IOR(PcsEmulLineLpbkCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &pcs_lpb));
    DRV_IOR_FIELD(lchip, PcsEmulLineLpbkCtl_t, fld_en, err_en, &pcs_lpb);
    DRV_IOR_FIELD(lchip, PcsEmulLineLpbkCtl_t, fld_cs, t_cycle, &pcs_lpb);
    DRV_IOR_FIELD(lchip, PcsEmulLineLpbkCtl_t, fld_cn, cycle_num, &pcs_lpb);
    DRV_IOR_FIELD(lchip, PcsEmulLineLpbkCtl_t, fld_bn, bit_num, &pcs_lpb);

    return CTC_E_NONE;
}

void
_sys_tmg_mac_show_emu_pcslpbk_err_inj(uint8 lchip)
{
    uint32 i = 0;
    uint32 lsd_rx = 0;
    uint32 err_en[16] = {0};
    uint32 t_cycle[16] = {0};
    uint32 cycle_num[16] = {0};
    uint32 bit_num[16] = {0};

    for(i = 0; i < 16; i++)
    {
        lsd_rx = 16+i;
        _sys_tmg_mac_get_emu_pcslpbk_err_inj(lchip, lsd_rx, &(err_en[i]), &(t_cycle[i]), &(cycle_num[i]), &(bit_num[i]));
        printf("SerDes %u RX: ", lsd_rx);
        if(err_en[i] == 0)
        {
            printf("error free\n");
        }
        else
        {
            if(bit_num[i] == 0)
            {
                printf("NA bits reversed in cycle ");
            }
            else
            {
                printf("%u bits reversed in cycle ", bit_num[i]);
            }

            if(cycle_num[i] == 0)
            {
                printf("NA\n");
            }
            else
            {
                printf("%u~%u (per %u cycles)\n", 0, (cycle_num[i] - 1), t_cycle[i]);
            }
        }
    }
}

int32
_sys_tmg_mac_set_emu_pcslpbk_mode(uint8 lchip, uint32 mode)
{

    uint32 cmd      = 0;
    PcsEmulLineLpbkCtl_m pcs_lpb;
    
    cmd = DRV_IOR(PcsEmulLineLpbkCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &pcs_lpb));
    DRV_IOW_FIELD_NZ(lchip, PcsEmulLineLpbkCtl_t, PcsEmulLineLpbkCtl_cfgEmulPcsLpbkMode_f, &mode, &pcs_lpb, 0, 0);
    cmd = DRV_IOW(PcsEmulLineLpbkCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &pcs_lpb));

    return CTC_E_NONE;
}

void
_sys_tmg_mac_show_emu_pcslpbk_mode(uint8 lchip)
{
    uint32 cmd      = 0;
    uint32 mode     = 0;
    PcsEmulLineLpbkCtl_m pcs_lpb;
    
    cmd = DRV_IOR(PcsEmulLineLpbkCtl_t, DRV_ENTRY_FLAG);
    (void)(DRV_IOCTL(lchip, 0, cmd, &pcs_lpb));
    DRV_IOR_FIELD(lchip, PcsEmulLineLpbkCtl_t, PcsEmulLineLpbkCtl_cfgEmulPcsLpbkMode_f, &mode, &pcs_lpb);

    if(0 == mode)
    {
        printf("serdes           serdes\n");
        printf("16 <>         <> 24    \n");
        printf("17 <>         <> 25    \n");
        printf("18 <>         <> 26    \n");
        printf("19 <>         <> 27    \n");
        printf("\n");
        printf("20 <>         <> 28    \n");
        printf("21 <>         <> 29    \n");
        printf("22 <>         <> 30    \n");
        printf("23 <>         <> 31    \n");
    }
    else if(1 == mode)
    {
        printf("serdes           serdes\n");
        printf("16 <-----------> 20    \n");
        printf("17 <-----------> 21    \n");
        printf("18 <-----------> 22    \n");
        printf("19 <-----------> 23    \n");
        printf("\n");
        printf("24 <-----------> 28    \n");
        printf("25 <-----------> 29    \n");
        printf("26 <-----------> 30    \n");
        printf("27 <-----------> 31    \n");
    }
    else
    {
        printf("serdes           serdes\n");
        printf("16 <-----------> 24    \n");
        printf("17 <-----------> 25    \n");
        printf("18 <-----------> 26    \n");
        printf("19 <-----------> 27    \n");
        printf("\n");
        printf("20 <-----------> 28    \n");
        printf("21 <-----------> 29    \n");
        printf("22 <-----------> 30    \n");
        printf("23 <-----------> 31    \n");
    }

}
#endif

#if defined(EMULATION_ENV)
int32
_sys_tmg_mac_set_macshim_reset(uint8 lchip, uint16 txqm_id)
{
    uint32  cmd      = 0;
    uint32  index    = 0;
    uint32  value    = 0;
    MacShimGtxCfg_m           gtx_cfg;

    index = DRV_INS(txqm_id, 0);
 
    cmd = DRV_IOR(MacShimGtxCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &gtx_cfg));
    value   = 1;
    DRV_IOW_FIELD(lchip, MacShimGtxCfg_t, MacShimGtxCfg_resetMacShimGlobal_f, &value, &gtx_cfg);
    value   = 0;
    DRV_IOW_FIELD(lchip, MacShimGtxCfg_t, MacShimGtxCfg_resetMacShimGtxPma_f, &value, &gtx_cfg);
    DRV_IOW_FIELD(lchip, MacShimGtxCfg_t, MacShimGtxCfg_resetMacShimLocal_f, &value, &gtx_cfg);
    cmd = DRV_IOW(MacShimGtxCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &gtx_cfg));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_macshim_fifo_afull_thrd(uint8 lchip, uint16 mac_id)
{
    uint32  step     = 0;
    uint32  fld_id   = 0;
    uint32  cmd      = 0;
    uint32  index    = 0;
    uint32  txqm     = SYS_TMG_GET_TXQM_BY_MAC_ID(mac_id);
    uint32  txqm_mac = SYS_TMG_GET_INNER_MAC_ID(mac_id);
    uint32  value    = 0;
    MacShimCalRxCtl_m ms_crx;
    MacShimFifoAFullThrdCfg_m afull_cfg;
    // MacShimGtxCfg_m           gtx_cfg;

    index = DRV_INS(txqm, 0);

    if(txqm_mac == 0)
    {
        cmd = DRV_IOR(MacShimCalRxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_crx));
        value = 1;
        DRV_IOW_FIELD(lchip, MacShimCalRxCtl_t, MacShimCalRxCtl_initCal_f, &value, &ms_crx);
        cmd = DRV_IOW(MacShimCalRxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_crx));       
    }

    cmd = DRV_IOR(MacShimFifoAFullThrdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &afull_cfg));
    value   = 900;
    step    = MacShimFifoAFullThrdCfg_macShimRxChan1RdThrd_f - MacShimFifoAFullThrdCfg_macShimRxChan0RdThrd_f;
    fld_id  = MacShimFifoAFullThrdCfg_macShimRxChan0RdThrd_f + step * txqm_mac;
    DRV_IOW_FIELD(lchip, MacShimFifoAFullThrdCfg_t, fld_id, &value, &afull_cfg);
    cmd = DRV_IOW(MacShimFifoAFullThrdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &afull_cfg));

    return CTC_E_NONE;
}


int32
_sys_tmg_mac_set_macshimcalrx(uint8 lchip, uint32 txqm, uint32 txqm_mac, uint32 value)
{
    uint32  cmd      = 0;
    uint32  index    = 0;
    MacShimCalRx_m ms_cfg;

    index = DRV_INS(txqm, txqm_mac);
    cmd = DRV_IOR(MacShimCalRx_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));
    DRV_IOW_FIELD(lchip, MacShimCalRx_t, MacShimCalRx_calEntry_f, &value, &ms_cfg);
    cmd = DRV_IOW(MacShimCalRx_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));
    
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_macshim_base_vlan_id(uint8 lchip, uint16 txqm_id)
{
    uint32  cmd       = 0;
    uint32  index     = 0;
    uint32  value = 0;
    MacShimRegCfg_m ms_cfg;


    /*write chip 0 tbl-reg MacShimRegCfg.0 0 field base1gVlanId 32*/
    index = DRV_INS(txqm_id, 0);
    cmd = DRV_IOR(MacShimRegCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));
    value = 32+((txqm_id%5)*512);
    DRV_IOW_FIELD_NZ(lchip, MacShimRegCfg_t, MacShimRegCfg_base1gVlanId_f, &value, &ms_cfg,   txqm_id, 0);
    value = 0+((txqm_id%5)*512);
    DRV_IOW_FIELD_NZ(lchip, MacShimRegCfg_t, MacShimRegCfg_base10gVlanId_f, &value, &ms_cfg,  txqm_id, 0);
    value = 64+((txqm_id%5)*512);
    DRV_IOW_FIELD_NZ(lchip, MacShimRegCfg_t, MacShimRegCfg_base25gVlanId_f, &value, &ms_cfg,  txqm_id, 0);
    value = 128+((txqm_id%5)*512);
    DRV_IOW_FIELD_NZ(lchip, MacShimRegCfg_t, MacShimRegCfg_base40gVlanId_f, &value, &ms_cfg,  txqm_id, 0);
    value = 192+((txqm_id%5)*512);
    DRV_IOW_FIELD_NZ(lchip, MacShimRegCfg_t, MacShimRegCfg_base50gVlanId_f, &value, &ms_cfg,  txqm_id, 0);
    value = 256+((txqm_id%5)*512);
    DRV_IOW_FIELD_NZ(lchip, MacShimRegCfg_t, MacShimRegCfg_base100gVlanId_f, &value, &ms_cfg, txqm_id, 0);
    cmd = DRV_IOW(MacShimRegCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_macshim_speed_ctl(uint8 lchip, uint16 txqm_id)
{
    uint32  cmd      = 0;
    uint32  index    = 0;
    uint32  value    = 1;
    MacShimRegCfg_m ms_cfg;
    MacShimInterruptFatal_m ms_int;
    
    index = DRV_INS(txqm_id, 0);
    cmd = DRV_IOR(MacShimRegCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));
    DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_cfgSpeedCtlReady_f, &value, &ms_cfg);
    cmd = DRV_IOW(MacShimRegCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));

    cmd = DRV_IOR(MacShimInterruptFatal_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_int));
    DRV_IOW_FIELD(lchip, MacShimInterruptFatal_t, MacShimInterruptFatal_xgmacTxAnomalyDropFlg_f, &value, &ms_int);
    cmd = DRV_IOW(MacShimInterruptFatal_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_int));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_macshim_port_speed(uint8 lchip, uint16 mac_id, uint8 if_mode)
{
    uint32  cmd      = 0;
    uint32  index    = 0;
    uint32  txqm     = SYS_TMG_GET_TXQM_BY_MAC_ID(mac_id);
    uint32  txqm_mac = SYS_TMG_GET_INNER_MAC_ID(mac_id);
    uint32  value    = 0;
    MacShimRegCfg_m ms_cfg;

    index = DRV_INS(txqm, 0);
    cmd = DRV_IOR(MacShimRegCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));
    /*1. unset speed ready*/
    value = 0;
    DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_cfgSpeedCtlReady_f, &value, &ms_cfg);
    cmd = DRV_IOW(MacShimRegCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));
    
    /*2. change speed mode*/

    switch(if_mode)
    {
        case CTC_CHIP_SERDES_SGMII_MODE:
        case CTC_CHIP_SERDES_2DOT5G_MODE:
            value = 0;
            break;
        case CTC_CHIP_SERDES_XFI_MODE:
            value = 5;
            break;
        case CTC_CHIP_SERDES_XXVG_MODE:
            value = 6;
            break;
        case CTC_CHIP_SERDES_XLG_MODE:
            value = 7;
            break;
        case CTC_CHIP_SERDES_LG_MODE:
            value = 8;
            break;
        case CTC_CHIP_SERDES_CG_MODE:
            value = 9;
            break;
        default:
            break;
    }

    DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_port0SpeedMode_f+txqm_mac, &value, &ms_cfg);

    value = (CTC_CHIP_SERDES_2DOT5G_MODE == if_mode) ? 50 : 0;
    DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_cfgShimDivPort0_f+txqm_mac, &value, &ms_cfg);

    value =  (CTC_CHIP_SERDES_2DOT5G_MODE == if_mode) ? 1 : 0;
    DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_cfgSpeedExtendEnPort0_f+txqm_mac, &value, &ms_cfg);
    
    cmd = DRV_IOW(MacShimRegCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));

    /* 3. set speed ready*/
    value = 1;
    DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_cfgSpeedCtlReady_f, &value, &ms_cfg);
    cmd = DRV_IOW(MacShimRegCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));

    return CTC_E_NONE;
}


int32
_sys_tmg_mac_set_macshim_intr_fatal(uint8 lchip, uint32 value)
{
    uint32  cmd      = 0;
    uint32  index    = 0;
    uint32  txqm     = 0;
    MacShimInterruptFatal_m ms_if;

    for(txqm = 0; txqm < 11; txqm++)
    {
        index = DRV_INS(txqm, 1);
        cmd = DRV_IOR(MacShimInterruptFatal_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_if));
        DRV_IOW_FIELD(lchip, MacShimInterruptFatal_t, MacShimInterruptFatal_xgmacTxAnomalyDropFlg_f, &value, &ms_if);
            cmd = DRV_IOW(MacShimInterruptFatal_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_if));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_pcs_emu_datasel(uint8 lchip, uint32 mode)
{
    uint32 cmd      = 0;
    PcsEmulDataSelCfg_m pcs_ds;
    
    cmd = DRV_IOR(PcsEmulDataSelCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &pcs_ds));
    DRV_IOW_FIELD_NZ(lchip, PcsEmulDataSelCfg_t, PcsEmulDataSelCfg_cfgPcsUnitDataSel0Hs2_f, &mode, &pcs_ds, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, PcsEmulDataSelCfg_t, PcsEmulDataSelCfg_cfgPcsUnitDataSel0Hs3_f, &mode, &pcs_ds, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, PcsEmulDataSelCfg_t, PcsEmulDataSelCfg_cfgPcsUnitDataSel1Hs2_f, &mode, &pcs_ds, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, PcsEmulDataSelCfg_t, PcsEmulDataSelCfg_cfgPcsUnitDataSel1Hs3_f, &mode, &pcs_ds, 0, 0);
    cmd = DRV_IOW(PcsEmulDataSelCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &pcs_ds));

    CTC_ERROR_RETURN(_sys_tmg_mac_set_emu_pcslpbk_mode(lchip, 2));

    return CTC_E_NONE;
}
#endif

int32
_sys_tmg_mac_set_mac_config(uint8 lchip, uint16 mac_id)
{
    uint16 if_mode      = 0;
    uint16 serdes_speed = 0;

    sys_dmps_db_upt_info_t port_info = {0};

    DP_DEBUG_FUNCTION_CALLED_PRINT();

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PSD_SPEED);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PSD_SPEED, serdes_speed);
    
    if(0 == serdes_speed)
    {
        if_mode = CTC_CHIP_SERDES_XFI_MODE;
    }
    else
    {
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);
    }

    switch(if_mode)
    {
        case CTC_CHIP_SERDES_SGMII_MODE:
        case CTC_CHIP_SERDES_2DOT5G_MODE:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_sgmii_config(lchip, mac_id));
            break;
        case CTC_CHIP_SERDES_XFI_MODE:
        case CTC_CHIP_SERDES_XXVG_MODE:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_xfi_xxvg_config(lchip, mac_id));
            break;
        case CTC_CHIP_SERDES_XLG_MODE:
        case CTC_CHIP_SERDES_CG_MODE:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_xlg_cg_config(lchip, mac_id));
            break;
        case CTC_CHIP_SERDES_LG_MODE:
            CTC_ERROR_RETURN(_sys_tmg_mac_set_lg_config(lchip, mac_id));
            break;
        default:
            break;
    }
#if defined(EMULATION_ENV) && !defined(EMULATOR_ENV)
    CTC_ERROR_RETURN(_sys_tmg_mac_set_macshim_port_speed(lchip, mac_id, if_mode));
#endif

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

/*temperaily fix for 100G fec-none*/
int32 
_sys_tmg_mac_set_mii_rsvd(uint8 lchip, uint8 mac_group_id)
{
    uint16 core_pll = 0;
    uint32 value    = 0;
    uint32 tbl_id   = 0;
    uint32 fld_id   = 0;
    uint32 cmd      = 0;
    uint32 index    = 0;
    SharedMiiReserved_m rsvd;

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_core_pll(lchip, &core_pll, 1));

    tbl_id = SharedMiiReserved_t;
    fld_id = SharedMiiReserved_reserved_f;
    cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    index  = DRV_INS(mac_group_id, 0);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rsvd));

    DRV_IOR_FIELD(lchip, tbl_id, fld_id, &value, &rsvd);

    if(core_pll < 800)
    {
        CTC_BIT_SET(value, 0);
    }
    else
    {
        CTC_BIT_UNSET(value, 0);
    }

    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &value, &rsvd, mac_group_id, 0);

    cmd    = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rsvd));
    
    return CTC_E_NONE;
}

int32 
_sys_tmg_mac_group_config(uint8 lchip, uint8 txqm_id)
{
    uint32 mac_idx = 0;
#if defined(EMULATION_ENV) || defined(TMG_SERDES_SIM)
    uint8  hss_id;
    uint16 psd;
#endif
    uint8 start_mac_grp   = 0;
    uint8 end_mac_grp     = 0;
    uint8 mac_grp         = 0;
    uint8 is_powerup      = 0;
    
    sys_dmps_mac_api_db_t api_db = {0};

    if(SYS_TMG_CPUMAC_TXQM_ID == txqm_id)
    {
        start_mac_grp = SYS_TMG_CPUMAC_HSS_ID;
        end_mac_grp   = SYS_TMG_CPUMAC_HSS_ID;
    }
    else
    {       
        start_mac_grp = txqm_id * SYS_TMG_HSS_NUM_PER_TXQM;
        end_mac_grp   = txqm_id * SYS_TMG_HSS_NUM_PER_TXQM + 1;
    }

    is_powerup = _sys_tmg_mac_is_power_up(lchip, txqm_id);

    /*is powerup*/
    if(is_powerup)
    {
        for(mac_grp = start_mac_grp; mac_grp <= end_mac_grp; mac_grp++)
        {
            api_db.mac_grp_idx = mac_grp;
    
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp, "// mac_group_id %d pre cfg start !!!\n",api_db.mac_grp_idx);
    
            CTC_ERROR_RETURN(_sys_tmg_mac_set_mii_rsvd(lchip, mac_grp));
            
            for(mac_idx = 0; mac_idx < SYS_TMG_QMAC_NUM; mac_idx++)
            {
                api_db.mac_idx = mac_idx;
                api_db.pcs_grp_idx = mac_grp;
                api_db.pcs_idx = mac_idx;
                DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FAULT_MASK_LINK, lchip, &api_db, 1);
    
#if defined(EMULATION_ENV)
                hss_id = mac_grp;
                psd = mac_idx + hss_id * SYS_TMG_LANE_NUM_PER_HSS;
                DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_LINK_FILTER,     lchip, &api_db, 0, 0);
                DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FAULT_FILTER,    lchip, &api_db, 0);
                DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FORCE_SIGDET,    lchip, &api_db, 1);
                CTC_ERROR_RETURN(sys_usw_dmps_serdes_set_rx_force_sigdet(lchip, mac_grp*SYS_TMG_LANE_NUM_PER_HSS+mac_idx, 1));
                /*not matter link partner , config bit reverse 1*/
                CTC_ERROR_RETURN(sys_tmg_serdes_set_trx_bit_reverse(lchip, hss_id, 1, &psd, 1));
#elif defined(TMG_SERDES_SIM)
                hss_id = mac_grp;
                psd = mac_idx + hss_id * SYS_TMG_LANE_NUM_PER_HSS;
                DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_LINK_FILTER,     lchip, &api_db, 0, 0);
                DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FAULT_FILTER,    lchip, &api_db, 0);
                DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FORCE_SIGDET,    lchip, &api_db, 0);
                CTC_ERROR_RETURN(sys_usw_dmps_serdes_set_rx_force_sigdet(lchip, mac_grp*SYS_TMG_LANE_NUM_PER_HSS+mac_idx, 0));
                /*not matter link partner , config bit reverse 1*/
                CTC_ERROR_RETURN(sys_tmg_serdes_set_trx_bit_reverse(lchip, hss_id, 1, &psd, 1));
#else
                DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_LINK_FILTER,     lchip, &api_db, 1, 100);
#endif
            }
    
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp, "// mac_group_id %d pre cfg end !!!\n",api_db.mac_grp_idx);
            
        }    
    }
    else
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_group_enable(lchip, txqm_id, FALSE));
    }
    
    return CTC_E_NONE;
}


int32
_sys_tmg_mac_init_pre_cfg(uint8 lchip)
{
    uint32 mac_grp = 0;
    uint32 mac_idx = 0;
#if defined(EMULATION_ENV) || defined(TMG_SERDES_SIM)
    uint8  hss_id;
    uint16 psd;
#endif
    sys_dmps_mac_api_db_t api_db = {0};

    DP_DEBUG_FUNCTION_CALLED_PRINT();
    
    /*SharedMiixCfg_cfgMiiFaultMaskLinkEn0_f 1*/
    /*SharedMiixCfg_cfgMiiRxLinkFilterEn0_f 1*/
    /*SharedMiixCfg_cfgMiiRxLinkFilterTimer0_f ?*/
    for(mac_grp = 0; mac_grp < SYS_TMG_MAC_GROUP_NUM; mac_grp++)
    {
        api_db.mac_grp_idx = mac_grp;

        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp, "// mac_group_id %d pre cfg start !!!\n",api_db.mac_grp_idx);

        CTC_ERROR_RETURN(_sys_tmg_mac_set_mii_rsvd(lchip, mac_grp));
        
        for(mac_idx = 0; mac_idx < SYS_TMG_QMAC_NUM; mac_idx++)
        {
            api_db.mac_idx = mac_idx;
            api_db.pcs_grp_idx = mac_grp;
            api_db.pcs_idx = mac_idx;
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FAULT_MASK_LINK, lchip, &api_db, 1);

#if defined(EMULATION_ENV) || defined(TMG_SERDES_SIM)
            hss_id = mac_grp;
            psd = mac_idx;
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_LINK_FILTER,     lchip, &api_db, 0, 0);
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FAULT_FILTER,    lchip, &api_db, 0);
#if defined(EMULATION_ENV)
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FORCE_SIGDET,    lchip, &api_db, 1);
            CTC_ERROR_RETURN(sys_usw_dmps_serdes_set_rx_force_sigdet(lchip, mac_grp*SYS_TMG_LANE_NUM_PER_HSS+mac_idx, 1));
#else
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FORCE_SIGDET,    lchip, &api_db, 0);
            CTC_ERROR_RETURN(sys_usw_dmps_serdes_set_rx_force_sigdet(lchip, mac_grp*SYS_TMG_LANE_NUM_PER_HSS+mac_idx, 0));
#endif
            /*not matter link partner , config bit reverse 1*/
            CTC_ERROR_RETURN(sys_tmg_serdes_set_trx_bit_reverse(lchip, hss_id, 1, &psd, 1));
#else
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_LINK_FILTER,     lchip, &api_db, 1, 100);
#endif
        }

        SYS_DMPS_DUMP_PRINT(g_tm_dump_fp, "// mac_group_id %d pre cfg end !!!\n",api_db.mac_grp_idx);

    }

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_init_post_cfg(uint8 lchip)
{
    uint16 txqm_id = 0;

#if defined(EMULATION_ENV) && !defined(EMULATOR_ENV)
    for(txqm_id = 0; txqm_id < SYS_TMG_CPUMAC_TXQM_ID; txqm_id++)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macshim_speed_ctl(lchip, txqm_id));
    }

    sal_task_sleep(200);
    
    for(txqm_id = 0; txqm_id < SYS_TMG_CPUMAC_TXQM_ID; txqm_id++)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macshim_base_vlan_id(lchip, txqm_id));
    }

    CTC_ERROR_RETURN(_sys_tmg_mac_set_emu_pcslpbk_mode(lchip, 2));
    CTC_ERROR_RETURN(_sys_tmg_mac_set_pcs_emu_datasel(lchip, 0));
    CTC_ERROR_RETURN(_sys_tmg_mac_set_macshim_intr_fatal(lchip, 1));
#endif

    /* unmask link intr */
    CTC_ERROR_RETURN(_sys_tmg_unmask_link_intr(lchip));
    /* unmask m2c intr */
    CTC_ERROR_RETURN(_sys_tmg_cpumac_init_m2c(lchip));
    /* cl73 aneth init */
    CTC_ERROR_RETURN(_sys_tmg_mac_cl73_init(lchip));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_link_filter(uint8 lchip, uint16 dport, uint32 filter_len)
{
    uint32 value = filter_len * 10;
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_LINK_FILTER, lchip, &api_db, 
        ((0 == filter_len) ? 0 : 1), value);
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_link_filter(uint8 lchip, uint16 dport, uint32* p_filter_len)
{
    uint32 en = 0;
    uint32 value = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_LINK_FILTER, lchip, &api_db, 
        &en, &value);
    SYS_USW_VALID_PTR_WRITE(p_filter_len, ((0 == en) ? 0 : value/10));
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_fault_filter(uint8 lchip, uint16 dport, uint32 filter_len)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FAULT_FILTER, lchip, &api_db, 
        ((0 == filter_len) ? 0 : 1));
    
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_fault_filter(uint8 lchip, uint16 dport, uint32* p_en)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_PTR_VALID_CHECK(p_en);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_FAULT_FILTER, lchip, &api_db, 
        p_en);

    return CTC_E_NONE;    
}

int32
_sys_tmg_mac_set_tx_force_fault(uint8 lchip, uint16 dport, uint32 fault_bmp)

{
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_TX_FORCE_FAULT, lchip, &api_db, fault_bmp);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_tx_force_fault(uint8 lchip, uint16 dport, uint32* p_fault_bmp)
{
    uint32 value                        = 0;
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_TX_FORCE_FAULT, lchip, &api_db, &value);

    *p_fault_bmp &= (~((uint32)CTC_PORT_FAULT_FORCE)); /*clear bit 3*/
    if(0 != value) /*set bit 3*/
    {
        *p_fault_bmp |= CTC_PORT_FAULT_FORCE;
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_link_fault(uint8 lchip, uint16 dport, uint32 *p_value)
{
    uint32 value            = 0;
    uint32 fault_bitmap     = 0;

    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_LINK_FAULT, lchip, &api_db, &value);

    fault_bitmap = (value ? (0x0 | (0x1 << (value - 1))) : 0);
    *p_value = (((*p_value) & 0xfffffff8) | (fault_bitmap & 0x00000007));

    return CTC_E_NONE;
    
}

int32 
_sys_tmg_mac_get_pcs_link_status(uint8 lchip, uint16 dport, uint32* p_is_up)
{
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_PCS_STATUS, lchip, &api_db, p_is_up);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_cl37_an_remote_status(uint8 lchip, uint16 lport, uint32 auto_neg_mode, uint32* p_speed, uint32* p_link)
{
    uint16 dport                 = 0;
    sys_dmps_mac_api_db_t api_db = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_CL37_REMOTE_STATUS, lchip, &api_db, auto_neg_mode, p_speed, p_link);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_link_info(uint8 lchip, uint16 lport, void* p_value)
{
    uint16 dport               = 0;
    ctc_port_link_info_t*   p_link_info = (ctc_port_link_info_t*)p_value;
    uint32 unidir_en           = p_link_info->unidir_en;
    uint32 fault               = p_link_info->fault;
    uint32 link_filter         = p_link_info->link_filter;
    uint32 fault_filter        = p_link_info->fault_filter;
    uint32 fault_filter_en     = (fault_filter == 0) ? 0 : 1;
    uint32 cur_unidir_en       = 0;
    uint32 cur_fault           = 0;
    uint32 cur_link_filter     = 0;
    uint32 cur_fault_filter    = 0;

    if((25 < link_filter) || (25 < fault_filter))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% filter length %u %u(ms) not support, max 25ms! lport %u\n", 
            link_filter, fault_filter, lport);
        return CTC_E_INVALID_PARAM;
    }

    if((link_filter == 0) && (fault_filter != 0))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Register limit:can not only enable fault filter!\n");
        return CTC_E_INVALID_PARAM;
    }

    if((link_filter != 0) && (fault_filter != 0) && (link_filter != fault_filter))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Register limit:when both enable,link filter length should be same as fault filter length!\n");
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(_sys_tmg_mac_get_unidir_en(lchip, dport, &cur_unidir_en));
    if(cur_unidir_en != unidir_en)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_unidir_en(lchip, dport, unidir_en));
    }

    CTC_ERROR_RETURN(_sys_tmg_mac_get_tx_force_fault(lchip, dport, &cur_fault));
    if(CTC_FLAG_ISSET(fault, CTC_PORT_FAULT_FORCE) != CTC_FLAG_ISSET(cur_fault, CTC_PORT_FAULT_FORCE))
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_tx_force_fault(lchip, dport, fault));
    }

    CTC_ERROR_RETURN(_sys_tmg_mac_get_link_filter(lchip, dport, &cur_link_filter));
    if(cur_link_filter != link_filter)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_link_filter(lchip, dport, link_filter));
    }

    CTC_ERROR_RETURN(_sys_tmg_mac_get_fault_filter(lchip, dport, &cur_fault_filter));
    if(cur_fault_filter != fault_filter_en)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_fault_filter(lchip, dport, fault_filter_en));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_link_info(uint8 lchip, uint16 lport, void* p_value)
{
    uint8  serdes_idx          = 0;
    uint16 dport               = 0;
    uint32 is_link_up          = 0;
    uint32 mac_link_status     = 0;
    uint32 pcs_link_status     = 0;
    uint32 unidir_en           = 0;
    uint32 fault               = 0;
    uint32 signal_detect       = 0;
    uint32 serdes_ready        = 0;
    uint32 link_filter         = 0;
    uint32 fault_filter_en     = 0;
    uint32 err_cnt[CTC_PORT_SERDES_MAX_NUM]        = {0};
    ctc_port_link_info_t*   p_link_info = (ctc_port_link_info_t*)p_value;

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(_sys_tmg_mac_get_link_up(lchip, dport, 0, SYS_MAC_MII_LINK_FM, &is_link_up));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_link_up(lchip, dport, 0, SYS_MAC_MII_LINK_RAW, &mac_link_status));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_pcs_code_err(lchip, dport, &err_cnt[0]));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_pcs_link_status(lchip, dport, &pcs_link_status));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_unidir_en(lchip, dport, &unidir_en));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_link_fault(lchip, dport, &fault));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_tx_force_fault(lchip, dport, &fault));
    
    CTC_ERROR_RETURN(_sys_tmg_mac_get_link_filter(lchip, dport, &link_filter));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_fault_filter(lchip, dport, &fault_filter_en));
    
    p_link_info->is_link_up      = (uint8)is_link_up;
    p_link_info->mac_link_status = (uint8)mac_link_status;
    p_link_info->pcs_link_status = (uint8)pcs_link_status;
    p_link_info->unidir_en       = (uint8)unidir_en;
    p_link_info->fault           = (uint8)fault;
    p_link_info->signal_detect   = (uint8)signal_detect;
    p_link_info->serdes_ready    = (uint8)serdes_ready;
    p_link_info->link_filter     = (uint16)link_filter;
    p_link_info->fault_filter    = (uint16)(fault_filter_en == 0 ? 0 : link_filter);
    for(serdes_idx = 0; serdes_idx < CTC_PORT_SERDES_MAX_NUM; serdes_idx++)
    {    
        p_link_info->pcs_err_cnt[serdes_idx]  = err_cnt[serdes_idx];
    }
    
    return CTC_E_NONE;
}


int32
_sys_tmg_mac_set_force_sigdet(uint8 lchip, uint16 dport, uint32 sigdet)
{
    uint8  lsd_num = 0;
    uint8  idx;
    uint16 lsd[DMPS_MAX_NUM_PER_MODULE] = {0};
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_LSD, &lsd_num, lsd));

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    for(idx = 0; idx < lsd_num; idx++)
    {
        api_db.pcs_idx = lsd[idx];
        DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FORCE_SIGDET, lchip, &api_db, sigdet);
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_force_sigdet(uint8 lchip, uint16 dport, uint32* p_sigdet)
{
    uint8  lsd_num = 0;
    uint8  idx;
    uint32 sigdet_sum = 1;
    uint32 sigdet[DMPS_MAX_NUM_PER_MODULE] = {0};
    uint16 lsd[DMPS_MAX_NUM_PER_MODULE] = {0};
    sys_dmps_mac_api_db_t   api_db      = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_LSD, &lsd_num, lsd));

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    for(idx = 0; idx < lsd_num; idx++)
    {
        api_db.pcs_idx = lsd[idx];
        DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_FORCE_SIGDET, lchip, &api_db, &(sigdet[idx]));
        if(0 == sigdet[idx])
        {
            sigdet_sum = 0;
            break;
        }
    }
    *p_sigdet = sigdet_sum;

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_init_mac_cfg(uint8 lchip)
{   
    uint8  txqm_id   = 0;
    uint16 mac_id    = 0;
    uint8  if_mode   = 0;
    uint8  port_type = 0;
    uint16 start_mac = 0;
    uint16 end_mac   = 0;
    
    sys_dmps_db_upt_info_t port_info = {0};

    DP_DEBUG_FUNCTION_CALLED_PRINT();

    //CTC_ERROR_RETURN(_sys_tmg_mac_init_pre_cfg(lchip));

#if defined(EMULATION_ENV) && !defined(EMULATOR_ENV)
    for(txqm_id = 0; txqm_id < SYS_TMG_CPUMAC_TXQM_ID; txqm_id++)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macshim_reset(lchip, txqm_id));
    }

    sal_task_sleep(200);
    
    for(txqm_id = 0; txqm_id < SYS_TMG_CPUMAC_TXQM_ID; txqm_id++)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_macshim_base_vlan_id(lchip, txqm_id));
    }
#endif
    for(txqm_id = 0; txqm_id <= SYS_TMG_CPUMAC_TXQM_ID; txqm_id++)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_group_config(lchip, txqm_id));

        start_mac   = txqm_id * SYS_TMG_MAC_NUM_PER_TXQM;
        end_mac     = start_mac + ((txqm_id == SYS_TMG_CPUMAC_TXQM_ID) ?  SYS_TMG_CPUMAC_SERDSES_NUM :  SYS_TMG_MAC_NUM_PER_TXQM);
        
        for(mac_id = start_mac; mac_id < end_mac; mac_id++)
        {
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, port_type);
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);

            SYS_CONDITION_CONTINUE(!SYS_USW_IS_NETWORK_PORT(port_type));

#if defined(EMULATION_ENV) && !defined(EMULATOR_ENV)
            CTC_ERROR_RETURN(_sys_tmg_mac_set_macshim_fifo_afull_thrd(lchip, mac_id));
            CTC_ERROR_RETURN(_sys_tmg_mac_set_macshim_port_speed(lchip, mac_id, if_mode));
#endif

            SYS_CONDITION_CONTINUE(FALSE == _sys_tmg_mac_is_power_up(lchip, txqm_id));

            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp, "// mac_id %d if_mode %d  mac init cfg start!!!!\n", mac_id, if_mode);
            CTC_ERROR_RETURN(_sys_tmg_mac_set_mac_config(lchip, mac_id));
            SYS_DMPS_DUMP_PRINT(g_tm_dump_fp, "// mac_id %d if_mode %d  mac init cfg end!!!!\n", mac_id, if_mode);
        }
    }

    CTC_ERROR_RETURN(_sys_tmg_mac_init_post_cfg(lchip));

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_init_intr_default(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 cpumac_bitmap = 0x055550FF;

    /*clear link intr*/
    /*unmask link intr*/
    ///TODO: cpumac bitmap diff tm2-tmg?
    index = DRV_INS(0, 1);
    cmd = DRV_IOW(CpuMacProcInterruptFunc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_bitmap));
    index = DRV_INS(0, 3);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_bitmap));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_mii_rst(uint8 lchip, uint16 lport, uint32 dir, uint32* p_enable)
{
    uint16 dport  = DMPS_INVALID_VALUE_U16;
    sys_dmps_mac_api_db_t     api_db = {0};
    sys_dmps_db_upt_info_t port_info = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));
    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_MII_RST, lchip, &api_db, dir, p_enable);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_pcs_rst(uint8 lchip, uint16 lport, uint32 dir, uint32* p_enable)
{
    uint16 dport  = DMPS_INVALID_VALUE_U16;
    sys_dmps_mac_api_db_t     api_db = {0};
    sys_dmps_db_upt_info_t port_info = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));
    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_PCS_RST, lchip, &api_db, dir, p_enable);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_mac_pkt_en(uint8 lchip, uint16 dport, uint8 dir, uint32 enable)
{
    sys_dmps_mac_api_db_t     api_db = {0};
    sys_dmps_db_upt_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, dir %s, enable %u\n", 
        __FUNCTION__, lchip, dport, ((dir == DMPS_RX) ? "RX" : "TX"), enable);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));
    
    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_PKT_EN, lchip, &api_db, dir, enable);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_mac_pkt_en(uint8 lchip, uint16 dport, uint8 dir, uint32* p_enable)
{
    sys_dmps_mac_api_db_t     api_db = {0};
    sys_dmps_db_upt_info_t port_info = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_PKT_EN, lchip, &api_db, dir, p_enable);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_dir_en(uint8 lchip, uint16 dport, uint8 direcion, uint32 enable)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    uint8 dir = (CTC_INGRESS == direcion) ? DMPS_RX : DMPS_TX;

    CTC_ERROR_RETURN(_sys_tmg_mac_set_mac_pkt_en(lchip, dport, dir, enable));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_dir_en(uint8 lchip, uint16 dport, uint8 direcion, uint32* p_enable)
{
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    uint8 dir = (CTC_INGRESS == direcion) ? DMPS_RX : DMPS_TX;

    CTC_ERROR_RETURN(_sys_tmg_mac_get_mac_pkt_en(lchip, dport, dir, p_enable));

    return CTC_E_NONE;
}

///TODO:
/*set directional property in dmps, moved from sys_usw_port.c*/
int32
_sys_tmg_mac_set_direction_property(uint8 lchip, uint16 lport,
                                    ctc_port_direction_property_t port_prop, ctc_direction_t dir, uint32 value)
{
    uint16 dport        = DMPS_INVALID_VALUE_U16;
    uint32 egress_value = value;
    int32  ret          = CTC_E_NONE;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set port property with direction, lport:%u, property:%d, dir:%d,\
        value:%d\n", lport, port_prop, dir, value);

    //SYS_MAC_INIT_CHECK();
    CTC_MAX_VALUE_CHECK(dir, CTC_BOTH_DIRECTION);

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    /*do write*/
    if ((CTC_INGRESS == dir) || (CTC_BOTH_DIRECTION == dir))
    {
        switch (port_prop)
        {
            case CTC_PORT_DIR_PROP_MAC_EN:
                value = (value) ? TRUE : FALSE;
                ret = _sys_tmg_mac_set_dir_en(lchip, dport, CTC_INGRESS, value);
                break;
            default:
                return CTC_E_INVALID_PARAM;
        }
    }

    value = egress_value;

    if ((CTC_EGRESS == dir) || (CTC_BOTH_DIRECTION == dir))
    {
        switch (port_prop)
        {
            case CTC_PORT_DIR_PROP_MAC_EN:
                value = (value) ? TRUE : FALSE;
                ret = _sys_tmg_mac_set_dir_en(lchip, dport, CTC_EGRESS, value);
                break;
            default:
                return CTC_E_INVALID_PARAM;
        }
    }

    CTC_ERROR_RETURN(ret);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_direction_property(uint8 lchip, uint16 lport,
                                    ctc_port_direction_property_t port_prop, ctc_direction_t dir, uint32* p_value)
{
    uint16 dport = DMPS_INVALID_VALUE_U16;
    int32  ret   = CTC_E_NONE;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get port property with direction, lport:%u, property:%d, dir:%d\n", 
        lport, port_prop, dir);

    //SYS_MAC_INIT_CHECK();
    //CTC_MAX_VALUE_CHECK(dir, CTC_BOTH_DIRECTION - 1);

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    /*do read, only get value by CTC_INGRESS or CTC_EGRESS, no CTC_BOTH_DIRECTION*/
    if (CTC_INGRESS == dir)
    {
        switch (port_prop)
        {
            case CTC_PORT_DIR_PROP_MAC_EN:
                ret = _sys_tmg_mac_get_dir_en(lchip, dport, CTC_INGRESS, p_value);
                break;
            default:
                return CTC_E_INVALID_PARAM;

        }
    }
    else if (CTC_EGRESS == dir)
    {
        switch (port_prop)
        {
            case CTC_PORT_DIR_PROP_MAC_EN:
                ret = _sys_tmg_mac_get_dir_en(lchip, dport, CTC_EGRESS, p_value);
                break;
            default:
                return CTC_E_INVALID_PARAM;
        }
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(ret);

    return CTC_E_NONE;
}

int32 
_sys_tmg_unmask_intr_hsctl(uint8 lchip, uint8 group_id)
{   
    uint32 index     = 0;
    uint32 cmd       = 0;
    uint32 value     = 0;
    uint32 tbl_id    = 0;

    CtcHsCtlInterruptFunc_m  CtcHsCtlInterruptFunc;

    /* #1, index, tbl_id, field_id */
    index = DRV_INS(group_id, 3);
    tbl_id    = CtcHsCtlInterruptFunc_t;

    /* #2, read HW table */
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CtcHsCtlInterruptFunc));

    /* #3. modify field value */
    value = 1;
    DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcHsCtlInterruptFunc_ctcPcsCtlInterruptFunc_f, &value, &CtcHsCtlInterruptFunc, group_id, 3);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcHsCtlInterruptFunc_ctcMacCtlInterruptFunc_f, &value, &CtcHsCtlInterruptFunc, group_id, 3);

    /* #4, write HW table */
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CtcHsCtlInterruptFunc));

    return CTC_E_NONE;
}

int32
_sys_tmg_unmask_link_intr(uint8 lchip)
{
    uint8 txqm_id = 0;
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 cpumac_bitmap = 0xFF0;
    uint32 network_bitmap[2] = {0xFFFF00, 0};

    for(txqm_id = 0; txqm_id <= SYS_TMG_CPUMAC_TXQM_ID; txqm_id++)
    {
        SYS_CONDITION_CONTINUE(FALSE == _sys_tmg_mac_is_power_up(lchip, txqm_id));

        _sys_tmg_unmask_intr_hsctl(lchip, txqm_id);

        if (SYS_TMG_CPUMAC_TXQM_ID == txqm_id)
        {
            cmd = DRV_IOW(CpuMacProcInterruptFunc_t, DRV_ENTRY_FLAG);
            index = DRV_INS(0, 1);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_bitmap));
            index = DRV_INS(0, 3);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cpumac_bitmap));
        }
        else
        {
            cmd = DRV_IOW(CtcPcsCtlInterruptFunc_t, DRV_ENTRY_FLAG);
            index = DRV_INS(txqm_id, 1);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &network_bitmap));
            index = DRV_INS(txqm_id, 3);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &network_bitmap));
        }
    }

    return CTC_E_NONE;    
}

int32 
_sys_tmg_cpumac_init_m2c(uint8 lchip)
{
    uint32 index     = 0;
    uint32 cmd       = 0;
    uint32 value     = 0;
    uint32 tbl_id    = 0;

    MapIntrFuncExtEnCfg_m  MapIntrFuncExtEnCfg;

    /* #1, index, tbl_id, field_id */
    index = DRV_INS(0, 0);
    tbl_id    = MapIntrFuncExtEnCfg_t;

    /* #2, read HW table */
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &MapIntrFuncExtEnCfg));

    /* #3. modify field value */
    value = 1;
    DRV_IOW_FIELD_NZ(lchip, tbl_id, MapIntrFuncExtEnCfg_cfgEnFuncMiscMcuReqToHostCpu_f, &value, &MapIntrFuncExtEnCfg, 0, 0);

    /* #4, write HW table */
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &MapIntrFuncExtEnCfg));

    return CTC_E_NONE;    
}

int32
_sys_tmg_mac_init_cl73_ability(uint8 lchip, uint16 psd)
{
    uint16 dport = 0;
    sys_dmps_an_ability_t cl73_ability = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PSD, psd, DMPS_DB_TYPE_PORT, NULL, &dport));

    CTC_ERROR_RETURN(_sys_tmg_mac_set_cl73_ability_hw(lchip, dport, &cl73_ability));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_cl73_init(uint8 lchip)
{
    uint8 macro_id = 0;
    uint16 serdes_base  = 0;
    uint16 serdes_id    = 0;
    uint16 txqm_id = 0;

    for(macro_id = 0; macro_id < SYS_TMG_MAC_GROUP_NUM; macro_id++)
    {
        serdes_base  = macro_id * SYS_TMG_LANE_NUM_PER_HSS;
        txqm_id = SYS_TMG_GET_TXQM_BY_MAC_ID(serdes_base);
        if (!_sys_tmg_mac_is_power_up(lchip, txqm_id))
        {
            continue;
        }
        for(serdes_id = serdes_base; serdes_id < serdes_base + SYS_TMG_LANE_NUM_PER_HSS; serdes_id++)
        {
            CTC_ERROR_RETURN(_sys_tmg_mac_cl73_reg_acc_init(lchip, serdes_id, TRUE));
#ifdef EMULATION_ENV
            if(SYS_TMG_PSD_WITH_HSS32G_MODULE(serdes_id))
            {
                CTC_ERROR_RETURN(_sys_tmg_mac_init_cl73_ability(lchip, serdes_id));
            }
#else
            CTC_ERROR_RETURN(_sys_tmg_mac_init_cl73_ability(lchip, serdes_id));
#endif
        }
    }

    return CTC_E_NONE;
}

int32
sys_tmg_mac_init(uint8 lchip)
{
    /*g_flt_print_en = TRUE;*/

    DP_DEBUG_FUNCTION_CALLED_PRINT();

#ifdef TMG_SERDES_SIM
    g_print_tbl = 1;    
#endif

#if defined EMULATION_ENV && !defined(EMULATOR_ENV)

    CTC_ERROR_RETURN(_sys_tmg_mac_set_emu_pcslpbk_mode(lchip, 2));

#endif

    CTC_ERROR_RETURN(_sys_tmg_mac_init_pulse_cfg(lchip));

    //CTC_ERROR_RETURN(_sys_tmg_mac_init_intr_default(lchip));

    CTC_ERROR_RETURN(_sys_tmg_mac_init_mac_cfg(lchip));

#ifdef TMG_SERDES_SIM
    g_print_tbl = 0;    
#endif

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    /*link intr func regist moved from port api*/
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP0_MC_MAC0, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP0_MC_MAC1, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP0_MC_MAC2, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP0_MC_MAC3, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP0_MC_MAC4, sys_usw_port_api_mac_isr_dispatch));

    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP1_MC_MAC0, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP1_MC_MAC1, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP1_MC_MAC2, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP1_MC_MAC3, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_DP1_MC_MAC4, sys_usw_port_api_mac_isr_dispatch));
    CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_CPU_MAC, sys_usw_port_api_mac_isr_dispatch));

    /*dmps db wb move to port api*/

    /*g_flt_print_en = FALSE;*/

    /*test code: unmask hsctl, enable cpumac m2c */


    return CTC_E_NONE;
}

STATIC int32
_sys_tmg_mac_isr_linkstat_handler(uint8 lchip, uint8 txqm_id, uint32 value[])
{
    uint8  an_en        = 0;
    uint8  mac_en       = 0;
    uint8  lane_id      = 0;
    uint8  lane_max     = (SYS_TMG_CPUMAC_TXQM_ID == txqm_id) ? SYS_TMG_CPUMAC_SERDSES_NUM : SYS_TMG_PCS_LANE_NUM;    
    uint16 lsd          = 0;    
    uint16 lport        = 0;    
    uint16 dport        = 0;
    uint32 status       = 0;
    uint32  is_up       = 0;    
    sys_dmps_db_upt_info_t port_info = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ 0x%x\n", "value[0]", value[0]);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ 0x%x\n", "value[1]", value[1]);

    if ((0 == value[0]) && (0 == value[1]))
    {
        return CTC_E_NONE;
    }

    for (lane_id = 0; lane_id < lane_max; lane_id++)
    {
        if ((!CTC_IS_BIT_SET(value[0], lane_id)) && (!CTC_IS_BIT_SET(value[1], lane_id)))
        {
            continue;
        }

        lsd = lane_id + txqm_id * SYS_TMG_PCS_LANE_NUM;

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info,      DMPS_DB_LOGIC_SERDES, lsd);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN, 0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,     0);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info,      DMPS_DB_DPORT,      dport);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN, an_en);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,     mac_en);

        CTC_ERROR_RETURN(_sys_tmg_mac_get_pcs_link_status(lchip, dport, &is_up));
        lport = sys_usw_dmps_db_get_lport_by_dport(lchip, dport);

        if ((((CTC_IS_BIT_SET(value[0], lane_id)) && (CTC_IS_BIT_SET(value[1], lane_id))) && is_up)
                || ((!CTC_IS_BIT_SET(value[0], lane_id)) && (CTC_IS_BIT_SET(value[1], lane_id))))
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "port %3d link_up\n", dport);
            if (an_en)
            {
                CTC_ERROR_RETURN(sys_tmg_mcu_send_link_up_intr(lchip, dport));
            }
        }
        else if ((((CTC_IS_BIT_SET(value[0], lane_id)) && (CTC_IS_BIT_SET(value[1], lane_id))) && (!is_up))
                    || ((CTC_IS_BIT_SET(value[0], lane_id)) && (!CTC_IS_BIT_SET(value[1], lane_id))))
        {
            if (an_en)
            {
                CTC_ERROR_RETURN(sys_tmg_mcu_get_anlt_state(lchip, dport, &status));
            }
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "port %3d link_down\n", dport);
        
            if (mac_en && an_en && (SYS_DMPS_ANLT_SM_STATE_AN_RUNNING != status))
            {
                if ((SYS_DMPS_ANLT_SM_STATE_LINK_UP != status) || (!is_up))
                {
                    CTC_ERROR_RETURN(_sys_usw_dmps_set_mac_en(lchip, lport, FALSE, FALSE));
                    CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_restart_an_msg(lchip, dport));
                    sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_AN_RESTART, 3);
                }
                else
                {
                    CTC_ERROR_RETURN(sys_usw_dmps_anlt_sm_send_link_down_msg(lchip, dport, is_up));
                }
            }
        }
    }

    return CTC_E_NONE;   
}

int32
_sys_tmg_mac_isr_m2c_handler(uint8 lchip, uint8 inst_id)
{
    uint32 cmd           = 0;
    uint32 m_intr_ctl[4] = {0x0};
    uint32 entry_id      = 0;
    uint32 index         = 0;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC,  "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "inst_id", inst_id);

    sal_sem_give(p_usw_mac_master[lchip]->p_dmps_msg_sem);

    /* Clear isr */
    sal_memset(m_intr_ctl, 0xff, sizeof(m_intr_ctl));

    index = DRV_INS(inst_id, entry_id);
    cmd   = DRV_IOW(McpuIntrIntCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &m_intr_ctl));

    return CTC_E_NONE;
}

int32 
_sys_tmg_clear_intr_pcsctl(uint8 lchip, uint8 txqm_id, uint32 field_id)
{   
    uint32 index     = 0;
    uint32 cmd       = 0;
    uint32 value     = 0;
    uint32 tbl_id    = 0;

    CtcPcsCtlInterruptFunc_m  CtcPcsCtlInterruptFunc;

    /* #1, index, tbl_id, field_id */
    index = DRV_INS(txqm_id, 1);
    tbl_id    = CtcPcsCtlInterruptFunc_t;

    /* #2, read HW table */
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CtcPcsCtlInterruptFunc));

    /* #3. modify field value */
    value = 1;
    DRV_IOW_FIELD_NZ(lchip, tbl_id, field_id, &value, &CtcPcsCtlInterruptFunc, txqm_id, 1);

    /* #4, write HW table */
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CtcPcsCtlInterruptFunc));

    return CTC_E_NONE;
}

int32 
_sys_tmg_clear_intr_hsctl(uint8 lchip, uint8 group_id)
{   
    uint32 index     = 0;
    uint32 cmd       = 0;
    uint32 value     = 0;
    uint32 tbl_id    = 0;

    CtcHsCtlInterruptFunc_m  CtcHsCtlInterruptFunc;

    /* #1, index, tbl_id, field_id */
    index = DRV_INS(group_id, 1);
    tbl_id    = CtcHsCtlInterruptFunc_t;

    /* #2, read HW table */
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CtcHsCtlInterruptFunc));

    /* #3. modify field value */
    value = 1;
    DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcHsCtlInterruptFunc_ctcPcsCtlInterruptFunc_f, &value, &CtcHsCtlInterruptFunc, group_id, 1);
    DRV_IOW_FIELD_NZ(lchip, tbl_id, CtcHsCtlInterruptFunc_ctcMacCtlInterruptFunc_f, &value, &CtcHsCtlInterruptFunc, group_id, 1);

    /* #4, write HW table */
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CtcHsCtlInterruptFunc));

    return CTC_E_NONE;
}

int32
sys_tmg_mac_isr_event_dispatch(uint8 lchip, uint32 intr, void* p_data)
{
    uint8  group_id = 0;
    uint8  field_id = 0;
    uint8  idx      = 0;
    uint32 tbl_id   = 0;
    uint32 value    = 0;
    uint32 value1   = 0;
    uint32 value2   = 0;
    uint32 value3   = 0;
    uint32 index    = 0;
    uint32 cmd      = 0;
    uint32 link_value[2] = {0};    /* link_value[0]: 1 means linkdown; link_value[1]: 1 means linkup; */
    uint32 cpumac_intr[16][4] =
    {
        /* field,                                               lane_id,   word,   intr_val, */
        {CpuMacProcInterruptFunc_miiLinkDownInterruptFunc0_f,   0,         0,      11},
        {CpuMacProcInterruptFunc_miiLinkDownInterruptFunc1_f,   1,         0,      10},
        {CpuMacProcInterruptFunc_miiLinkDownInterruptFunc2_f,   2,         0,      9},
        {CpuMacProcInterruptFunc_miiLinkDownInterruptFunc3_f,   3,         0,      8},
        {CpuMacProcInterruptFunc_miiLinkUpInterruptFunc0_f,     0,         0,      7},
        {CpuMacProcInterruptFunc_miiLinkUpInterruptFunc1_f,     1,         0,      6},
        {CpuMacProcInterruptFunc_miiLinkUpInterruptFunc2_f,     2,         0,      5},
        {CpuMacProcInterruptFunc_miiLinkUpInterruptFunc3_f,     3,         0,      4},
    };

    uint32 network_intr[16][4] =
    {
        /* field,                                               lane_id,   word,   intr_val, */
        {CtcPcsCtlInterruptFunc_miiLinkDownInterruptFunc0_f,    0,         0,      8 },
        {CtcPcsCtlInterruptFunc_miiLinkDownInterruptFunc1_f,    1,         0,      9 },
        {CtcPcsCtlInterruptFunc_miiLinkDownInterruptFunc2_f,    2,         0,      10},
        {CtcPcsCtlInterruptFunc_miiLinkDownInterruptFunc3_f,    3,         0,      11},
        {CtcPcsCtlInterruptFunc_miiLinkDownInterruptFunc4_f,    4,         0,      12},
        {CtcPcsCtlInterruptFunc_miiLinkDownInterruptFunc5_f,    5,         0,      13},
        {CtcPcsCtlInterruptFunc_miiLinkDownInterruptFunc6_f,    6,         0,      14},
        {CtcPcsCtlInterruptFunc_miiLinkDownInterruptFunc7_f,    7,         0,      15},
        {CtcPcsCtlInterruptFunc_miiLinkUpInterruptFunc0_f,      0,         0,      16},
        {CtcPcsCtlInterruptFunc_miiLinkUpInterruptFunc1_f,      1,         0,      17},
        {CtcPcsCtlInterruptFunc_miiLinkUpInterruptFunc2_f,      2,         0,      18},
        {CtcPcsCtlInterruptFunc_miiLinkUpInterruptFunc3_f,      3,         0,      19},
        {CtcPcsCtlInterruptFunc_miiLinkUpInterruptFunc4_f,      4,         0,      20},
        {CtcPcsCtlInterruptFunc_miiLinkUpInterruptFunc5_f,      5,         0,      21},
        {CtcPcsCtlInterruptFunc_miiLinkUpInterruptFunc6_f,      6,         0,      22},
        {CtcPcsCtlInterruptFunc_miiLinkUpInterruptFunc7_f,      7,         0,      23},
    };

    sys_usw_intr_isr_data_t *p_isr_data = (sys_usw_intr_isr_data_t*)p_data;

    CtcPcsCtlInterruptFunc_m CtcPcsCtlInterruptFunc;

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "lchip", lchip);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ %d\n", "intr",  intr);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "        %-32s @ 0x%08x \n", "status", p_isr_data->status[0]);

    switch(intr)
    {
        case SYS_INTR_FUNC_DP0_MC_MAC0:
            group_id = 0;
            break;
        case SYS_INTR_FUNC_DP0_MC_MAC1: 
            group_id = 1;
            break;
        case SYS_INTR_FUNC_DP0_MC_MAC2: 
            group_id = 2;
            break;
        case SYS_INTR_FUNC_DP0_MC_MAC3: 
            group_id = 3;
            break;
        case SYS_INTR_FUNC_DP0_MC_MAC4: 
            group_id = 4;
            break;
        case SYS_INTR_FUNC_DP1_MC_MAC0: 
            group_id = 5;
            break;
        case SYS_INTR_FUNC_DP1_MC_MAC1: 
            group_id = 6;
            break;
        case SYS_INTR_FUNC_DP1_MC_MAC2: 
            group_id = 7;
            break;
        case SYS_INTR_FUNC_DP1_MC_MAC3: 
            group_id = 8;
            break;
        case SYS_INTR_FUNC_DP1_MC_MAC4: 
            group_id = 9;
            break;
        case SYS_INTR_FUNC_CPU_MAC:
            group_id = 10;
            break;
        default:
            break;    
    }

    /* CPUMAC */
    if(SYS_TMG_CPUMAC_TXQM_ID == group_id)
    {
        /* link intr */
        for(idx = 0; idx < 4; idx++)
        {
            if(CTC_IS_BIT_SET(p_isr_data->status[0], cpumac_intr[idx][3]))
            {
                CTC_BIT_SET(link_value[0], cpumac_intr[idx][1]);
                continue;
            }
        }
        for(idx = 4; idx < 8; idx++)
        {
            if(CTC_IS_BIT_SET(p_isr_data->status[0], cpumac_intr[idx][3]))
            {
                CTC_BIT_SET(link_value[1], cpumac_intr[idx][1]);
                continue;
            }
        }        
        CTC_ERROR_RETURN(_sys_tmg_mac_isr_linkstat_handler(lchip, group_id, link_value));
    }
    /* NW */
    else
    {
        /* link intr */
        index = DRV_INS(group_id, 0);
        cmd = DRV_IOR(CtcHsCtlInterruptFunc_t, CtcHsCtlInterruptFunc_ctcPcsCtlInterruptFunc_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value1));

        if (1 == value1)
        {
            index = DRV_INS(group_id, 0);
            tbl_id = CtcPcsCtlInterruptFunc_t;  
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &CtcPcsCtlInterruptFunc));

            for (idx = 0; idx < 8; idx++)
            {
                field_id = network_intr[idx][0];
                DRV_IOR_FIELD(lchip, tbl_id, field_id, &value, &CtcPcsCtlInterruptFunc);
                CTC_ERROR_RETURN(_sys_tmg_clear_intr_pcsctl(lchip, group_id, field_id));
                if (1 == value)
                {
                    CTC_BIT_SET(link_value[0], network_intr[idx][1]);
                    continue;
                }
            }
            for (idx = 8; idx < 16; idx++)
            {
                field_id = network_intr[idx][0];
                DRV_IOR_FIELD(lchip, tbl_id, field_id, &value, &CtcPcsCtlInterruptFunc);
                CTC_ERROR_RETURN(_sys_tmg_clear_intr_pcsctl(lchip, group_id, field_id));
                if (1 == value)
                {
                    CTC_BIT_SET(link_value[1], network_intr[idx][1]);
                    continue;
                }
            }
            CTC_ERROR_RETURN(_sys_tmg_mac_isr_linkstat_handler(lchip, group_id, link_value));
        }

        /* m2c intr */
        index = DRV_INS(group_id, 0);
        cmd = DRV_IOR(CtcHsCtlInterruptFunc_t, CtcHsCtlInterruptFunc_ctcMacCtlInterruptFunc_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value2));
        if (1 == value2)
        {
            index = DRV_INS(group_id, 0);
            cmd = DRV_IOR(CtcHsCtlInterruptFunc1_t, CtcHsCtlInterruptFunc1_intrToRlmValid_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value3));
            if (value3 == 1)
            {
                CTC_ERROR_RETURN(_sys_tmg_mac_isr_m2c_handler(lchip, group_id));
            }
        }
        CTC_ERROR_RETURN(_sys_tmg_clear_intr_hsctl(lchip, group_id));
    }

    return CTC_E_NONE;
}

int32 
_sys_tmg_mac_set_link_intr(uint8 lchip, uint16 dport, uint8 enable)
{
    uint8  inst_id      = 0;
    uint8  inner_mac_id = 0;
    uint16 mac_id       = 0;
    uint16 port_type    = 0;
    uint32 tbl_id       = 0;
    uint32 index        = 0;
    uint32 cmd          = 0;
    uint32 cpumac_val[1] = {0};
    uint32 nw_val[2]     = {0};
    sys_dmps_db_upt_info_t     port_info = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, port_type);

    inner_mac_id = SYS_TMG_GET_INNER_MAC_ID(mac_id);

    if(SYS_USW_IS_CPUMAC_PORT(port_type))
    {
        inst_id = 0;
        tbl_id  = CpuMacProcInterruptFunc_t;
        cmd     = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_BIT_SET(cpumac_val[0], (7  - inner_mac_id));   /* link up */
        CTC_BIT_SET(cpumac_val[0], (11 - inner_mac_id));   /* link down */

        if(enable)
        {
            /*clear link intr*/
            index = DRV_INS(inst_id, 1);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, (void*)cpumac_val));
            /*unmask link intr*/
            index = DRV_INS(inst_id, 3);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, (void*)cpumac_val));
        }
        else
        {
            /*mask link intr*/
            index = DRV_INS(inst_id, 2);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, (void*)cpumac_val));
        }
    }
    else
    {
        inst_id = SYS_TMG_GET_TXQM_BY_MAC_ID(mac_id);
        tbl_id  = CtcPcsCtlInterruptFunc_t;
        cmd     = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_BIT_SET(nw_val[0], (16 + inner_mac_id));   /* link up */
        CTC_BIT_SET(nw_val[0], (8  + inner_mac_id));   /* link down */

        if(enable)
        {
            /*clear link intr*/
            index = DRV_INS(inst_id, 1);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, (void*)nw_val));
            /*unmask link intr*/
            index = DRV_INS(inst_id, 3);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, (void*)nw_val));
        }
        else
        {
            /*mask link intr*/
            index = DRV_INS(inst_id, 2);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, (void*)nw_val));
        }
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_LINK_INTR_EN, ((enable) ? 1 : 0));
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));

    return CTC_E_NONE;
}

int32 
_sys_tmg_mac_get_link_intr(uint8 lchip, uint16 dport, uint32* p_enable)
{
    uint8  inst_id      = 0;
    uint8  inner_mac_id = 0;
    uint16 port_type    = 0;
    uint16 mac_id       = 0;
    uint32 tbl_id       = 0;
    uint32 index        = 0;
    uint32 value[1]     = {0};
    uint32 tbl_val[2]   = {0};
    uint32 cmd          = 0;
    sys_dmps_db_upt_info_t     port_info = {0};

    CTC_PTR_VALID_CHECK(p_enable);

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, port_type);

    inner_mac_id = SYS_TMG_GET_INNER_MAC_ID(mac_id);

    if(SYS_USW_IS_CPUMAC_PORT(port_type))
    {
        tbl_id       = CpuMacProcInterruptFunc_t;
        inst_id      = 0;

        CTC_BIT_SET(value[0], (7 - inner_mac_id));    /* link up */
        CTC_BIT_SET(value[0], (11 - inner_mac_id));   /* link down */
    }
    else
    {
        tbl_id       = CtcPcsCtlInterruptFunc_t;
        inst_id      = SYS_TMG_GET_TXQM_BY_MAC_ID(mac_id);

        CTC_BIT_SET(value[0], (16 + inner_mac_id));   /* link up */
        CTC_BIT_SET(value[0], (8  + inner_mac_id));   /* link down */
    }

    index = DRV_INS(inst_id, 2);
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, tbl_val));

    if(CTC_FLAG_ISSET(tbl_val[0], value[0]))
    {
        SYS_USW_VALID_PTR_WRITE(p_enable, 0);
    }
    else
    {
        SYS_USW_VALID_PTR_WRITE(p_enable, 1);
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_wait_mii_rx_up(uint8 lchip, uint16 dport)
{
    uint32 is_up = 0;
    uint32 times = 10000;

    while(--times)
    {

        (void)_sys_tmg_mac_get_mii_link_status(lchip, dport, SYS_MAC_MII_LINK_FM, &is_up);

        if(is_up)
        {
            return CTC_E_NONE;
        }
    }
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "%% RX MII is down! dport %u\n", dport);
    return CTC_E_NONE;
}

#if 0
int32
_sys_tmg_mac_pcs_link_fault_reset(uint8 lchip, uint16 dport)
{
    sys_dmps_mac_api_db_t     api_db = {0};
    uint32 intr_stat     = 0;
    uint32 unidir_en     = 0;

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    if(!SYS_MAC_IS_MULTI_LANE_MODE(api_db.if_mode))
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_mac_pkt_en(lchip, dport, DMPS_RX, TRUE));
        return CTC_E_NONE;
    }

    /*1. disable interrupt*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_link_intr(lchip, dport, &intr_stat));

    if(0 != intr_stat)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_link_intr(lchip, dport, FALSE));
    }

    /*2. ignore fault: local fault, remote fault, link fault*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_unidir_en(lchip, dport, &unidir_en));
    
    if(0 == unidir_en)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_unidir_en(lchip, dport, TRUE));
    }

    /*3. do pcs rx reset*/
    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MAC_RX_EN, lchip, &api_db, FALSE);
    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MAC_RX_EN, lchip, &api_db, TRUE);
    /*3.1 set mac rx pkt en*/
    CTC_ERROR_RETURN(_sys_tmg_mac_wait_mii_rx_up(lchip, dport));
    CTC_ERROR_RETURN(_sys_tmg_mac_set_mac_pkt_en(lchip, dport, DMPS_RX, TRUE));

    /*4. care fault*/
    if(!unidir_en)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_unidir_en(lchip, dport, FALSE));
    }
    
    /*5. enable interrupt after operation*/
    if(0 != intr_stat)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_set_link_intr(lchip, dport, TRUE));
    }

    return CTC_E_NONE;
}
#endif

int32
sys_tmg_mac_pcs_status_check(uint8 lchip, uint16 lport, void* p_pcs_status)
{
    uint8  i            = 0;
    uint8  pcs_idx      = 0;
    uint8  pcs_group_id = 0;
    uint8  if_mode      = 0;
    uint8  loop         = 0;
    uint16 dport        = SYS_TMG_USELESS_ID16;
    uint32 index        = 0;
    uint32 tbl_id       = 0;
    uint32 fld_id       = 0;
    uint32 cmd          = 0;
    uint32 fec_val      = 0;
    sys_dmps_db_upt_info_t port_info = {0};
    sys_dmps_mac_api_db_t   api_db   = {0};

    uint32 pcs_sync       = SYS_TMG_USELESS_ID32;
    uint32 rsfec_lock     = SYS_TMG_USELESS_ID32;
    uint32 xgfec_lock     = SYS_TMG_USELESS_ID32;
    uint32 fec_am_lock    = SYS_TMG_USELESS_ID32;
    uint32 rx_block_lock  = SYS_TMG_USELESS_ID32;
    uint32 rx_am_lock     = SYS_TMG_USELESS_ID32;
    uint32 rx_cwm_lock    = SYS_TMG_USELESS_ID32;
    uint32 hi_ber         = SYS_TMG_USELESS_ID32;
    uint32 hi_ser         = SYS_TMG_USELESS_ID32;
    uint32 tmp_hi_ber     = 0;
    uint32 code_err_cnt   = SYS_TMG_USELESS_ID32;
    uint32 bip_err_cnt    = SYS_TMG_USELESS_ID32;
    uint32 err_blk_cnt    = SYS_TMG_USELESS_ID32;
    uint32 bad_ber_cnt    = SYS_TMG_USELESS_ID32;
    uint32 bip_err_total  = 0;
    uint32 err_blk_total  = 0;
    uint32 bad_ber_total  = 0;

    sys_pcs_status_t* pcs_status = (sys_pcs_status_t*)p_pcs_status;

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));
    if_mode = api_db.if_mode;
    pcs_idx = api_db.pcs_idx;
    fec_val = api_db.fec_type;
    pcs_group_id = api_db.pcs_grp_idx;

    /* rs fec lock */
    if((SYS_DMPS_FEC_TYPE_RS528 == fec_val) && ((CTC_CHIP_SERDES_XXVG_MODE == if_mode) || 
        (CTC_CHIP_SERDES_LG_MODE == if_mode) || (CTC_CHIP_SERDES_CG_MODE == if_mode)))
    {
        dmps_RsFec0StatusSharedFec_t(pcs_idx, tbl_id);
        fld_id = RsFec0StatusSharedFec_dbgRsFec0RxReady_f;
        index  = DRV_INS(pcs_group_id, 0);
        cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &RsFec0StatusSharedFec));
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rsfec_lock, &RsFec0StatusSharedFec);

        fld_id = RsFec0StatusSharedFec_dbgRsFec0RxMdHiSer_f;
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &hi_ser, &RsFec0StatusSharedFec);
    }

    /* fec am lock */
    if((SYS_DMPS_FEC_TYPE_RS528 == fec_val) && (CTC_CHIP_SERDES_XXVG_MODE == if_mode))
    {
        tbl_id = GlobalStatusSharedFec_t;
        dmps_GlobalStatusSharedFec_dbgSharedFecAmLock0_f(pcs_idx, fld_id);
        index  = DRV_INS(pcs_group_id, 0);
        cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &GlobalStatusSharedFec));
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &fec_am_lock, &GlobalStatusSharedFec);
    }
    else if((CTC_CHIP_SERDES_LG_MODE == if_mode) && (SYS_DMPS_FEC_TYPE_RS528 == fec_val))
    {
        tbl_id = GlobalStatusSharedFec_t;
        index  = DRV_INS(pcs_group_id, 0);
        cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &GlobalStatusSharedFec));
        if(2 <= pcs_idx)
        {
            for(fld_id = GlobalStatusSharedFec_dbgSharedFecAmLock2_f; fld_id <= GlobalStatusSharedFec_dbgSharedFecAmLock3_f; fld_id ++)
            {
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &fec_am_lock, &GlobalStatusSharedFec);
                if(0 == fec_am_lock)
                {
                    break;
                }
            }
        }
        else
        {
            for(fld_id = GlobalStatusSharedFec_dbgSharedFecAmLock0_f; fld_id <= GlobalStatusSharedFec_dbgSharedFecAmLock1_f; fld_id ++)
            {
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &fec_am_lock, &GlobalStatusSharedFec);
                if(0 == fec_am_lock)
                {
                    break;
                }
            }
        }
    }
    else if((CTC_CHIP_SERDES_CG_MODE == if_mode) && (SYS_DMPS_FEC_TYPE_RS528 == fec_val))
    {
        tbl_id = GlobalStatusSharedFec_t;
        index  = DRV_INS(pcs_group_id, 0);
        cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &GlobalStatusSharedFec));
        for(fld_id = GlobalStatusSharedFec_dbgSharedFecAmLock0_f; fld_id <= GlobalStatusSharedFec_dbgSharedFecAmLock3_f; fld_id ++)
        {
            cmd = DRV_IOR(tbl_id, fld_id);
            DRV_IOR_FIELD(lchip, tbl_id, fld_id, &fec_am_lock, &GlobalStatusSharedFec);
            if(0 == fec_am_lock)
            {
                break;
            }
        }
    }

    /* xg fec lock */
    if((SYS_DMPS_FEC_TYPE_FC2112 == fec_val) &&
        ((CTC_CHIP_SERDES_XXVG_MODE == if_mode)
        ||(CTC_CHIP_SERDES_XFI_MODE == if_mode)))
    {
        dmps_XgFec0StatusSharedFec_t((pcs_idx*2), tbl_id);
        fld_id = XgFec0StatusSharedFec_dbgXgFec0RxBlockLock_f;
        index  = DRV_INS(pcs_group_id, 0);
        cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &XgFec0StatusSharedFec));
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &xgfec_lock, &XgFec0StatusSharedFec);
    }
    else if((SYS_DMPS_FEC_TYPE_FC2112 == fec_val) && (CTC_CHIP_SERDES_XLG_MODE == if_mode))
    {
        fld_id = XgFec0StatusSharedFec_dbgXgFec0RxBlockLock_f;
        for (i = 0; i < 4; i++)  //XgFec0/2/4/6
        {
            dmps_XgFec0StatusSharedFec_t((i*2), tbl_id);
            index = DRV_INS(pcs_group_id, 0);
            cmd   = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &XgFec0StatusSharedFec));
            DRV_IOR_FIELD(lchip, tbl_id, fld_id, &xgfec_lock, &XgFec0StatusSharedFec);
            if(0 == xgfec_lock)
            {
                break;
            }
        }
    }
    else if((SYS_DMPS_FEC_TYPE_FC2112 == fec_val) && (CTC_CHIP_SERDES_LG_MODE == if_mode))
    {
        if(2 <= pcs_idx)
        {
            fld_id = XgFec0StatusSharedFec_dbgXgFec0RxBlockLock_f;
            for (i = 0; i < 4; i++)  //XgFec4~7
            {
                dmps_XgFec0StatusSharedFec_t((i+4), tbl_id);
                index  = DRV_INS(pcs_group_id, 0);
                cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &XgFec0StatusSharedFec));
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &xgfec_lock, &XgFec0StatusSharedFec);
                if(0 == xgfec_lock)
                {
                    break;
                }
            }
        }
        else
        {
            fld_id = XgFec0StatusSharedFec_dbgXgFec0RxBlockLock_f;
            for (i = 0; i < 4; i++)  //XgFec0~3
            {
                dmps_XgFec0StatusSharedFec_t(i, tbl_id);
                index  = DRV_INS(pcs_group_id, 0);
                cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &XgFec0StatusSharedFec));
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &xgfec_lock, &XgFec0StatusSharedFec);
                if(0 == xgfec_lock)
                {
                    break;
                }
            }
        }
    }

    /* rx_cwm_lock */
    //rx_cwm_lock = SYS_TMG_USELESS_ID32;

    /* rx block lock && rx_am_lock && err check */
    if((CTC_CHIP_SERDES_XFI_MODE == if_mode) || (CTC_CHIP_SERDES_XXVG_MODE == if_mode))
    {
        dmps_SharedPcsXfi0Status_t(pcs_idx, tbl_id);
        index  = DRV_INS(pcs_group_id, 0);
        cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsXfi0Status));
        fld_id = SharedPcsXfi0Status_badBerCnt0_f;
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &bad_ber_cnt, &SharedPcsXfi0Status);
        fld_id = SharedPcsXfi0Status_hiBer0_f;
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &hi_ber, &SharedPcsXfi0Status);
        fld_id = SharedPcsXfi0Status_errBlockCnt0_f;
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &err_blk_cnt, &SharedPcsXfi0Status);
    }
    else if((CTC_CHIP_SERDES_XLG_MODE == if_mode) || (CTC_CHIP_SERDES_CG_MODE == if_mode))
    {
        for (i = 0; i < 4; i++)  //0~3
        {
            dmps_SharedPcsXfi0Status_t(i, tbl_id);
            index  = DRV_INS(pcs_group_id, 0);
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsXfi0Status));
            fld_id = SharedPcsXfi0Status_badBerCnt0_f;
            DRV_IOR_FIELD(lchip, tbl_id, fld_id, &bad_ber_cnt, &SharedPcsXfi0Status);
            bad_ber_total += bad_ber_cnt;
            fld_id = SharedPcsXfi0Status_hiBer0_f;
            DRV_IOR_FIELD(lchip, tbl_id, fld_id, &hi_ber, &SharedPcsXfi0Status);
            tmp_hi_ber += hi_ber;
            fld_id = SharedPcsXfi0Status_errBlockCnt0_f;
            DRV_IOR_FIELD(lchip, tbl_id, fld_id, &err_blk_cnt, &SharedPcsXfi0Status);
            err_blk_total += err_blk_cnt;
        }
        bad_ber_cnt = bad_ber_total;
        err_blk_cnt = err_blk_total;
        hi_ber = tmp_hi_ber ? 1 : 0;
    }
    else if(CTC_CHIP_SERDES_LG_MODE == if_mode)
    {
        if(2 <= pcs_idx)
        {
            for (i = 0; i < 2; i++)  //2, 3
            {
                dmps_SharedPcsXfi0Status_t((i+2), tbl_id);
                index  = DRV_INS(pcs_group_id, 0);
                cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsXfi0Status));
                fld_id = SharedPcsXfi0Status_badBerCnt0_f;
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &bad_ber_cnt, &SharedPcsXfi0Status);
                bad_ber_total += bad_ber_cnt;
                fld_id = SharedPcsXfi0Status_hiBer0_f;
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &hi_ber, &SharedPcsXfi0Status);
                tmp_hi_ber += hi_ber;
                fld_id = SharedPcsXfi0Status_errBlockCnt0_f;
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &err_blk_cnt, &SharedPcsXfi0Status);
                err_blk_total += err_blk_cnt;
            }
            bad_ber_cnt = bad_ber_total;
            err_blk_cnt = err_blk_total;
            hi_ber = tmp_hi_ber ? 1 : 0;
        }
        else
        {
            for (i = 0; i < 2; i++)  //0, 1
            {
                dmps_SharedPcsXfi0Status_t(i, tbl_id);
                index  = DRV_INS(pcs_group_id, 0);
                cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsXfi0Status));
                fld_id = SharedPcsXfi0Status_badBerCnt0_f;
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &bad_ber_cnt, &SharedPcsXfi0Status);
                bad_ber_total += bad_ber_cnt;
                fld_id = SharedPcsXfi0Status_hiBer0_f;
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &hi_ber, &SharedPcsXfi0Status);
                tmp_hi_ber += hi_ber;
                fld_id = SharedPcsXfi0Status_errBlockCnt0_f;
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &err_blk_cnt, &SharedPcsXfi0Status);
                err_blk_total += err_blk_cnt;
            }
            bad_ber_cnt = bad_ber_total;
            err_blk_cnt = err_blk_total;
            hi_ber = tmp_hi_ber ? 1 : 0;
        }
    }
    else if((CTC_CHIP_SERDES_SGMII_MODE == if_mode) || (CTC_CHIP_SERDES_2DOT5G_MODE == if_mode))
    {
        dmps_SharedPcsSgmii0Status_t(pcs_idx, tbl_id);
        fld_id = SharedPcsSgmii0Status_codeErrCnt0_f;
        index  = DRV_INS(pcs_group_id, 0);
        cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsSgmii0Status));
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &code_err_cnt, &SharedPcsSgmii0Status);
    }

    if((CTC_CHIP_SERDES_XFI_MODE == if_mode) || (CTC_CHIP_SERDES_XXVG_MODE == if_mode))
    {
        dmps_SharedPcsXfi0Status_t(pcs_idx, tbl_id);
        index  = DRV_INS(pcs_group_id, 0);
        cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsXfi0Status));

        if(SYS_DMPS_FEC_TYPE_NONE == fec_val)
        {
            fld_id = SharedPcsXfi0Status_rxBlockLock0_f;
            DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rx_block_lock, &SharedPcsXfi0Status);
        }
    }
    else if(CTC_CHIP_SERDES_XLG_MODE == if_mode)
    {
        tbl_id = SharedPcsXlgStatus_t;
        index  = DRV_INS(pcs_group_id, 0);
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsXlgStatus));
        for(loop = 0; loop < 4; loop++)
        {
            dmps_SharedPcsXlgStatus_bipErrCnt0_f(loop, fld_id);
            DRV_IOR_FIELD(lchip, tbl_id, fld_id, &bip_err_cnt, &SharedPcsXlgStatus);
            bip_err_total += bip_err_cnt;
        }
        bip_err_cnt = bip_err_total;

        if(SYS_DMPS_FEC_TYPE_NONE == fec_val)
        {

            fld_id = SharedPcsXfi0Status_rxBlockLock0_f;
            for (i = 0; i < 4; i++)  //0~3
            {
                dmps_SharedPcsXfi0Status_t(i, tbl_id);
                index  = DRV_INS(pcs_group_id, 0);
                cmd = DRV_IOR(tbl_id, fld_id);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsXfi0Status));
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rx_block_lock, &SharedPcsXfi0Status);
                if(0 == rx_block_lock)
                {
                    break;
                }
            }
        }

        if((SYS_DMPS_FEC_TYPE_NONE == fec_val) || (SYS_DMPS_FEC_TYPE_FC2112 == fec_val))
        {
            for(fld_id = SharedPcsXlgStatus_rxAmLock0_f; fld_id <= SharedPcsXlgStatus_rxAmLock3_f; fld_id ++)
            {
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rx_am_lock, &SharedPcsXlgStatus);
                if(0 == rx_am_lock)
                {
                    break;
                }
            }
        }
    }
    else if(CTC_CHIP_SERDES_LG_MODE == if_mode)
    {
        if(2 <= pcs_idx)
        {
            tbl_id = SharedPcsLgStatus_t;
            index  = DRV_INS(pcs_group_id, 0);
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsLgStatus));
            for(loop = 0; loop < 4; loop++)
            {
                dmps_SharedPcsLgStatus_lgPcs1BipErrCnt0_f(loop, fld_id);
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &bip_err_cnt, &SharedPcsLgStatus);
                bip_err_total += bip_err_cnt;
            }
            bip_err_cnt = bip_err_total;
        }
        else
        {
            tbl_id = SharedPcsXlgStatus_t;
            index  = DRV_INS(pcs_group_id, 0);
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsXlgStatus));
            for(loop = 0; loop < 4; loop++)
            {
                dmps_SharedPcsXlgStatus_bipErrCnt0_f(loop, fld_id);
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &bip_err_cnt, &SharedPcsXlgStatus);
                bip_err_total += bip_err_cnt;
            }
            bip_err_cnt = bip_err_total;
        }

        if((SYS_DMPS_FEC_TYPE_FC2112 == fec_val) || (SYS_DMPS_FEC_TYPE_NONE == fec_val))
        {
            if(2 <= pcs_idx)
            {
                for(fld_id = SharedPcsLgStatus_lgPcs1RxAmLock0_f; fld_id <= SharedPcsLgStatus_lgPcs1RxAmLock3_f; fld_id ++)
                {
                    DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rx_am_lock, &SharedPcsLgStatus);
                    if(0 == rx_am_lock)
                    {
                        break;
                    }
                }
            }
            else
            {
                for(fld_id = SharedPcsXlgStatus_rxAmLock0_f; fld_id <= SharedPcsXlgStatus_rxAmLock3_f; fld_id ++)
                {
                    DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rx_am_lock, &SharedPcsXlgStatus);
                    if(0 == rx_am_lock)
                    {
                        break;
                    }
                }
            }
        }

        if(SYS_DMPS_FEC_TYPE_NONE == fec_val)
        {
            if(2 <= pcs_idx)
            {
                for(fld_id = SharedPcsLgStatus_lgPcs1RxBlockLock0_f; fld_id <= SharedPcsLgStatus_lgPcs1RxBlockLock3_f; fld_id ++)
                {
                    DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rx_block_lock, &SharedPcsLgStatus);
                    if(0 == rx_block_lock)
                    {
                        break;
                    }
                }
            }
            else
            {
                fld_id = SharedPcsXfi0Status_rxBlockLock0_f;
                for (i = 0; i < 4; i++)  //0~3
                {
                    dmps_SharedPcsXfi0Status_t(i, tbl_id);
                    index  = DRV_INS(pcs_group_id, 0);
                    cmd = DRV_IOR(tbl_id, fld_id);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsXfi0Status));
                    DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rx_block_lock, &SharedPcsXfi0Status);
                    if(0 == rx_block_lock)
                    {
                        break;
                    }
                }
            }
        }
    }
    else if(CTC_CHIP_SERDES_CG_MODE == if_mode)
        {
            tbl_id = SharedPcsCgStatus_t;
            index  = DRV_INS(pcs_group_id, 0);
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &SharedPcsCgStatus));
            for(loop = 0; loop < 20; loop++)
            {
                dmps_SharedPcsCgStatus_cgLane0BipErrCnt_f(loop, fld_id);
                DRV_IOR_FIELD(lchip, tbl_id, fld_id, &bip_err_cnt, &SharedPcsCgStatus);
                bip_err_total += bip_err_cnt;
            }
            bip_err_cnt = bip_err_total;

            if(SYS_DMPS_FEC_TYPE_NONE == fec_val)
            {
                for(fld_id = SharedPcsCgStatus_cgRxBlockLock0_f; fld_id <= SharedPcsCgStatus_cgRxBlockLock19_f; fld_id ++)
                {
                    DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rx_block_lock, &SharedPcsCgStatus);
                    if(0 == rx_block_lock)
                    {
                        break;
                    }
                }

                for(fld_id = SharedPcsCgStatus_cgRxAmLock0_f; fld_id <= SharedPcsCgStatus_cgRxAmLock19_f; fld_id ++)
                {
                    DRV_IOR_FIELD(lchip, tbl_id, fld_id, &rx_am_lock, &SharedPcsCgStatus);
                    if(0 == rx_am_lock)
                    {
                        break;
                    }
                }
            }
        }

    CTC_ERROR_RETURN(_sys_tmg_mac_get_pcs_link_status(lchip, dport, &pcs_sync));

    pcs_status->pcs_sync      = pcs_sync;
    pcs_status->hi_ber        = hi_ber;
    pcs_status->hi_ser        = hi_ser;
    pcs_status->bad_ber_cnt   = bad_ber_cnt;
    pcs_status->err_blk_cnt   = err_blk_cnt;
    pcs_status->code_err_cnt  = code_err_cnt;
    pcs_status->bip_err_cnt   = bip_err_cnt;
    pcs_status->rx_block_lock = rx_block_lock;
    pcs_status->rx_am_lock    = rx_am_lock;
    pcs_status->rx_cwm_lock   = rx_cwm_lock;
    pcs_status->fec_am_lock   = fec_am_lock;
    pcs_status->xgfec_lock    = xgfec_lock;
    pcs_status->rsfec_lock    = rsfec_lock;
    
    return CTC_E_NONE;
}

int32 
_sys_tmg_mac_get_fec_cnt(uint8 lchip, uint16 dport, void* p_value)
{
    uint32 correct_cnt   = 0;
    uint32 uncorrect_cnt = 0;
    ctc_port_fec_cnt_t*     fec_cnt   = (ctc_port_fec_cnt_t*)p_value;
    sys_dmps_mac_api_db_t   api_db;

    SYS_CONDITION_RETURN(!fec_cnt, CTC_E_INVALID_PTR);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "dport:0x%04X\n", dport);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    if(SYS_DMPS_FEC_TYPE_NONE == api_db.fec_type)    /*FEC : None*/
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " dport %d FEC is not enable.\n",dport);
        return CTC_E_INVALID_PARAM;
    }

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_FEC_CNT, lchip, &api_db, &uncorrect_cnt, &correct_cnt);
        
    fec_cnt->correct_cnt   = correct_cnt;
    fec_cnt->uncorrect_cnt = uncorrect_cnt;

    return  CTC_E_NONE;
}

int32
sys_tmg_mac_get_self_check_info(uint8 lchip, uint16 lport, void* p_self_check_info)
{
    uint8  if_mode             = 0;
    uint8  serdes_num          = 0;
    uint8  serdes_idx          = 0;
    uint8  speed_mode          = 0;
    uint8  if_type             = 0;
    uint8  lane_speed          = 0;
    uint8  group_pll_lock      = 0;
    uint8  lane_tx_pll_lock    = 0;
    uint8  lane_rx_pll_lock    = 0;
    uint8  sig_det             = 0;
    uint8  force_sig_det_en    = 0;
    uint8  force_sig_det_val   = 0;
    //uint8  rx_rdy              = 0;
    uint8  cdr_det_en          = 0;
    uint8  cdr_lock            = 0;
    uint8  tx_lane_en          = 0;
    uint8  rx_lane_en          = 0;
    uint8  tx_train_en         = 0;
    uint8  rx_train_en         = 0;
    uint8  tx_train_stat       = 0;
    uint8  rx_train_stat       = 0;
    uint8  fw_stat             = 0;
    uint8  tx_poly             = 0;
    uint8  rx_poly             = 0;
    //uint8  group_power_on      = 0;
    uint8  lane_tx_power_on    = 0;
    uint8  lane_rx_power_on    = 0;
    uint8  tx_prbs_en          = 0;
    uint8  rx_prbs_en          = 0;
    uint8  tx_prbs_pat         = 0;
    uint8  rx_prbs_pat         = 0;
    uint16 dport               = 0;
    uint16 chip_frequency      = 0;
    uint16 chan_id             = 0;
    uint16 mac_id              = 0;
    uint16 pcs_id              = 0;
    uint32 fec_val             = 0;
    uint32 an_en               = 0;
    uint32 mac_en              = 0;
    uint32 mac_rx_pkt_en       = 0;
    uint32 mac_tx_pkt_en       = 0;
    uint32 preamble_length     = 0;
    uint32 ipg_length          = 0;
    uint32 higig2_en           = 0;
    uint32 padding_en          = 0;
    uint32 check_crc_en        = 0;
    uint32 strip_crc_en        = 0;
    uint32 append_crc_en       = 0;
    uint32 append_tod_en       = 0;
    uint32 parallel_detect_en  = 0;
    uint32 an_mode             = 0;
    uint32 pcs_link_intr_en    = 0;
    uint32 unidir_en           = 0;
    uint32 tx_force_fault      = 0;
    uint32 pcs_rx_rst          = 0;
    uint32 pcs_tx_rst          = 0;
    uint32 mii_rx_rst          = 0;
    uint32 mii_tx_rst          = 0;
    uint32 link_mode           = 0;
    uint32 link_fsm            = 0;
    uint32 link_status         = 0;
    uint32 link_status_raw     = 0;
    uint32 cl73_local_ability  = 0;
    uint32 cl73_fec            = 0;
    uint32 link_filter_length  = 0;
    uint32 fault_filter_en     = 0;
    uint32 value               = 0;
    uint32 fault               = 0;
    uint32 lpbk_mode           = 0;
    uint32 eye_height          = 0;
    uint32 eye_width           = 0;
    uint32 sig_det_thrd        = 0;
    uint32 rx_prbs_cnt         = 0;
    uint32 anlt_state          = 0;
    uint16 logical_serdes[SYS_MAX_SERDES_NUM_PER_PORT]  = {0};
    uint16 physical_serdes[SYS_MAX_SERDES_NUM_PER_PORT] = {0};
    uint16 user_serdes[SYS_MAX_SERDES_NUM_PER_PORT]     = {0};
    ctc_port_fec_cnt_t     fec_cnt    = {0};
    sys_pcs_status_t       pcs_status = {0};
    sys_usw_dmps_serdes_id_t tmp_psd  = {{0}};
    sys_dmps_db_upt_info_t port_info  = {0};
    ctc_chip_serdes_ctle_t rx_ctle    = {0};
    ctc_chip_serdes_ffe_t  tx_eq      = {0};
    sys_usw_dmps_serdes_fw_version_t fw_ver = {0};
    ctc_chip_serdes_prbs_t prbs       = {0};
    sys_dmps_mac_self_check_info_t* self_check_info = (sys_dmps_mac_self_check_info_t*)p_self_check_info;

    CTC_PTR_VALID_CHECK(self_check_info);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get port mac self-check info, lport:%u\n", lport);

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,                dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_TYPE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_EN);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_FEC_TYPE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_PCS_ID,               pcs_id);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID,               mac_id);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_CHAN_ID,              chan_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE,    if_mode);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_TYPE,    if_type);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,          mac_en);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_FEC_TYPE,   fec_val);

    SYS_DMPS_GET_SERDES_NUM_BY_MODE(if_mode, serdes_num);

    SYS_CONDITION_RETURN(SYS_MAX_SERDES_NUM_PER_PORT < serdes_num, CTC_E_INVALID_PARAM);
    SYS_CONDITION_RETURN(SYS_PORT_SPEED_MAX <= speed_mode, CTC_E_INVALID_PARAM);
    SYS_CONDITION_RETURN(CTC_PORT_IF_MAX_TYPE <= if_type, CTC_E_INVALID_PARAM);

    /*Chip Info*/
    SELF_CHECK_ERROR_FILTER(sys_usw_get_chip_clock(lchip, &chip_frequency), chip_frequency);

    self_check_info->chip_frequency   = chip_frequency;

    /*Port Map*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_LSD, &serdes_num, logical_serdes));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_PSD, &serdes_num, physical_serdes));

    self_check_info->lport       = lport;
    self_check_info->chan_id     = chan_id;
    self_check_info->mac_id      = mac_id;
    self_check_info->pcs_id      = pcs_id;
    self_check_info->if_mode     = if_mode;
    self_check_info->serdes_num  = serdes_num;
    for(serdes_idx = 0; serdes_idx < serdes_num; serdes_idx++)
    {
        self_check_info->logical_serdes[serdes_idx]  = logical_serdes[serdes_idx];
        self_check_info->physical_serdes[serdes_idx] = physical_serdes[serdes_idx];
        self_check_info->user_serdes[serdes_idx]     = physical_serdes[serdes_idx];
    }

    /*Port Config*/
    if(SYS_MAC_IS_MODE_SUPPORT_CL37(if_mode))
    {
        SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_cl37_en(lchip, lport, &an_en), an_en);
    }
    else if(SYS_MAC_IS_MODE_SUPPORT_CL73(if_mode))
    {
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_db_get_cl73_en(lchip, lport, &an_en), an_en);
    }
    else
    {
        an_en = SYS_TMG_USELESS_ID32;
    }
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_direction_property(lchip, lport, CTC_PORT_DIR_PROP_MAC_EN, CTC_INGRESS, &mac_rx_pkt_en), mac_rx_pkt_en);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_direction_property(lchip, lport, CTC_PORT_DIR_PROP_MAC_EN, CTC_EGRESS, &mac_tx_pkt_en), mac_tx_pkt_en);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_frame_property(lchip, dport, CTC_PORT_PROP_PREAMBLE, &preamble_length), preamble_length);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_ipg(lchip, dport, &value), value);
    ipg_length = value & 0x000000ff;
    higig2_en  = value >> 8;
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_frame_property(lchip, dport, CTC_PORT_PROP_PADING_EN, &padding_en), padding_en);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_frame_property(lchip, dport, CTC_PORT_PROP_CHK_CRC_EN, &check_crc_en), check_crc_en);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_frame_property(lchip, dport, CTC_PORT_PROP_STRIP_CRC_EN, &strip_crc_en), strip_crc_en);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_frame_property(lchip, dport, CTC_PORT_PROP_APPEND_CRC_EN, &append_crc_en), append_crc_en);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_frame_property(lchip, dport, CTC_PORT_PROP_APPEND_TOD_EN, &append_tod_en), append_tod_en);
    if((CTC_CHIP_SERDES_SGMII_MODE == if_mode) || (CTC_CHIP_SERDES_2DOT5G_MODE == if_mode))
    {
        SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_parallel_detect_en(lchip, dport, &parallel_detect_en), parallel_detect_en);
    }
    else
    {
        parallel_detect_en = SYS_TMG_USELESS_ID32;
    }
    if(SYS_MAC_IS_MODE_SUPPORT_CL73(if_mode))
    {
        SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_cl73_ability(lchip, dport, 0, (void*)&cl73_local_ability), cl73_local_ability);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_db_get_an_fec(lchip, lport, &cl73_fec), cl73_fec);
    }
    else
    {
        cl73_local_ability = SYS_TMG_USELESS_ID32;
        cl73_fec           = SYS_TMG_USELESS_ID32;
    }
    if(SYS_MAC_IS_MODE_SUPPORT_CL37(if_mode))
    {
        SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_cl37_mode(lchip, lport, &an_mode), an_mode);
    }
    else if(SYS_MAC_IS_MODE_SUPPORT_CL73(if_mode))
    {
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_db_get_an_mode(lchip, lport, (uint8*)&an_mode), an_mode);
    }
    else
    {
        an_mode = SYS_TMG_USELESS_ID32;
    }
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_link_intr(lchip, dport, &pcs_link_intr_en), pcs_link_intr_en);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_unidir_en(lchip, dport, &unidir_en), unidir_en);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_link_filter(lchip, dport, &link_filter_length), link_filter_length);
    CTC_ERROR_RETURN(_sys_tmg_mac_get_fault_filter(lchip, dport, &fault_filter_en));
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_tx_force_fault(lchip, dport, &tx_force_fault), tx_force_fault);
    tx_force_fault = CTC_FLAG_ISSET(tx_force_fault, CTC_PORT_FAULT_FORCE);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_pcs_rst(lchip, lport, DMPS_RX, &pcs_rx_rst), pcs_rx_rst);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_pcs_rst(lchip, lport, DMPS_TX, &pcs_tx_rst), pcs_tx_rst);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_mii_rst(lchip, lport, DMPS_RX, &mii_rx_rst), mii_rx_rst);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_mii_rst(lchip, lport, DMPS_TX, &mii_tx_rst), mii_tx_rst);

    self_check_info->speed_mode          = speed_mode;
    self_check_info->if_type             = if_type;
    self_check_info->fec_val             = fec_val;
    self_check_info->an_en               = an_en;
    self_check_info->mac_en              = mac_en;
    self_check_info->mac_rx_pkt_en       = mac_rx_pkt_en;
    self_check_info->mac_tx_pkt_en       = mac_tx_pkt_en;
    self_check_info->preamble_length     = preamble_length;
    self_check_info->ipg_length          = ipg_length;
    self_check_info->higig2_en           = higig2_en;
    self_check_info->padding_en          = padding_en;
    self_check_info->check_crc_en        = check_crc_en;
    self_check_info->strip_crc_en        = strip_crc_en;
    self_check_info->append_crc_en       = append_crc_en;
    self_check_info->append_tod_en       = append_tod_en;
    self_check_info->parallel_detect_en  = parallel_detect_en;
    self_check_info->cl73_local_ability  = cl73_local_ability;
    self_check_info->cl73_fec            = cl73_fec;
    self_check_info->an_mode             = an_mode;
    self_check_info->pcs_link_intr_en    = pcs_link_intr_en;
    self_check_info->unidir_en           = unidir_en;
    self_check_info->link_filter_length  = link_filter_length;
    self_check_info->fault_filter_length = (0 == fault_filter_en) ? 0 : link_filter_length;
    self_check_info->tx_force_fault      = tx_force_fault;
    self_check_info->pcs_rx_rst          = pcs_rx_rst;
    self_check_info->pcs_tx_rst          = pcs_tx_rst;
    self_check_info->mii_rx_rst          = mii_rx_rst;
    self_check_info->mii_tx_rst          = mii_tx_rst;
    self_check_info->pcs_module          = SHAREDPCS;

    /*MAC Status*/
    SELF_CHECK_ERROR_FILTER(sys_usw_dmps_db_get_link_mode_by_dport(lchip, dport, &link_mode), link_mode);
    SELF_CHECK_ERROR_FILTER(sys_usw_dmps_db_get_link_fsm(lchip, lport, &link_fsm), link_fsm);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_link_up(lchip, dport, 0, SYS_MAC_MII_LINK_FM, &link_status), link_status);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_link_up(lchip, dport, 0, SYS_MAC_MII_LINK_RAW, &link_status_raw), link_status_raw);
    SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_link_fault(lchip, dport, &fault), fault);

    self_check_info->link_mode       = link_mode;
    self_check_info->link_fsm        = link_fsm;
    self_check_info->link_status     = link_status;
    self_check_info->link_status_raw = link_status_raw;
    self_check_info->local_fault     = CTC_FLAG_ISSET(fault, CTC_PORT_FAULT_LOCAL);
    self_check_info->remote_fault    = CTC_FLAG_ISSET(fault, CTC_PORT_FAULT_REMOTE);
    self_check_info->link_fault      = CTC_FLAG_ISSET(fault, CTC_PORT_FAULT_LINK);

    /*PCS Status*/
    /*place get_fec_cnt function here to avoid fec cnt read clear*/
    if(fec_val)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_get_fec_cnt(lchip, dport, (void*)&fec_cnt));
    }
    CTC_ERROR_RETURN(sys_tmg_mac_pcs_status_check(lchip, lport, (void*)&pcs_status));
    self_check_info->pcs_sync      = pcs_status.pcs_sync;
    self_check_info->hi_ber        = pcs_status.hi_ber;
    self_check_info->rx_block_lock = pcs_status.rx_block_lock;
    self_check_info->rx_am_lock    = pcs_status.rx_am_lock;
    self_check_info->rx_cwm_lock   = pcs_status.rx_cwm_lock;
    self_check_info->code_err_cnt  = pcs_status.code_err_cnt;
    self_check_info->bad_ber_cnt   = pcs_status.bad_ber_cnt;
    self_check_info->err_blk_cnt   = pcs_status.err_blk_cnt;
    self_check_info->bip_err_cnt   = pcs_status.bip_err_cnt;

    /*FEC Status*/
    self_check_info->hi_ser        = pcs_status.hi_ser;
    self_check_info->fec_am_lock   = pcs_status.fec_am_lock;
    self_check_info->xgfec_lock    = pcs_status.xgfec_lock;
    self_check_info->rsfec_lock    = pcs_status.rsfec_lock;
    self_check_info->correct_cnt   = fec_cnt.correct_cnt;
    self_check_info->uncorrect_cnt = fec_cnt.uncorrect_cnt;

    /*SerDes*/
    for(serdes_idx = 0; serdes_idx < serdes_num; serdes_idx++)
    {
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_speed(lchip, physical_serdes[serdes_idx],\
            DMPS_RX, &lane_speed), lane_speed);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_rx_sigdet(lchip, physical_serdes[serdes_idx],\
            &sig_det), sig_det);
        if(sys_usw_dmps_serdes_get_rx_force_sigdet(lchip, physical_serdes[serdes_idx],\
            &force_sig_det_en, &force_sig_det_val) < 0)
        {
            force_sig_det_en  = SYS_TMG_USELESS_ID8;
            force_sig_det_val = SYS_TMG_USELESS_ID8;
        }
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_group_pll_lock(lchip, physical_serdes[serdes_idx],\
            &group_pll_lock), group_pll_lock);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_pll_lock(lchip, physical_serdes[serdes_idx],\
            DMPS_TX, &lane_tx_pll_lock), lane_tx_pll_lock);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_pll_lock(lchip, physical_serdes[serdes_idx],\
            DMPS_RX, &lane_rx_pll_lock), lane_rx_pll_lock);

        self_check_info->serdes_info[serdes_idx].lane_speed        = lane_speed;
        self_check_info->serdes_info[serdes_idx].sig_det           = sig_det;
        self_check_info->serdes_info[serdes_idx].force_sig_det_en  = force_sig_det_en;
        self_check_info->serdes_info[serdes_idx].force_sig_det_val = force_sig_det_val;
        self_check_info->serdes_info[serdes_idx].group_pll_lock    = group_pll_lock;
        self_check_info->serdes_info[serdes_idx].lane_tx_pll_lock  = lane_tx_pll_lock;
        self_check_info->serdes_info[serdes_idx].lane_rx_pll_lock  = lane_rx_pll_lock;

        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_rx_cdr_lock(lchip, physical_serdes[serdes_idx],\
            &cdr_lock), cdr_lock);
        /*SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_rx_ready(lchip, physical_serdes[serdes_idx],\
            /&rx_rdy), rx_rdy);*/
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_rx_cdr_det_en(lchip, physical_serdes[serdes_idx],\
            &cdr_det_en), cdr_det_en);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_rx_eye_open(lchip, physical_serdes[serdes_idx],\
            DMPS_SERDES_EYE_HEIGHT, &eye_height), eye_height);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_rx_eye_open(lchip, physical_serdes[serdes_idx],\
            DMPS_SERDES_EYE_WIDTH, &eye_width), eye_width);

        self_check_info->serdes_info[serdes_idx].cdr_lock   = cdr_lock;
        //self_check_info->serdes_info[serdes_idx].rx_rdy     = rx_rdy;
        self_check_info->serdes_info[serdes_idx].cdr_det_en = cdr_det_en;
        self_check_info->serdes_info[serdes_idx].eye_height = eye_height;
        self_check_info->serdes_info[serdes_idx].eye_width  = eye_width;

        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_rx_sigdet_thrd(lchip, physical_serdes[serdes_idx],\
            &sig_det_thrd), sig_det_thrd);
        /*SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_rx_snr(lchip, physical_serdes[serdes_idx],\
            &snr), snr);*/
        tmp_psd.num = 1;
        tmp_psd.serdes[0] = physical_serdes[serdes_idx];
        SELF_CHECK_ERROR_FILTER(_sys_tmg_mac_get_loopback_mode(lchip, (void*)&tmp_psd, &lpbk_mode), lpbk_mode);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_polarity(lchip, physical_serdes[serdes_idx], DMPS_TX,\
            &tx_poly), tx_poly);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_polarity(lchip, physical_serdes[serdes_idx], DMPS_RX,\
            &rx_poly), rx_poly);

        self_check_info->serdes_info[serdes_idx].sig_det_thrd = sig_det_thrd;
        //self_check_info->serdes_info[serdes_idx].snr          = snr;
        self_check_info->serdes_info[serdes_idx].lpbk_mode    = lpbk_mode;
        self_check_info->serdes_info[serdes_idx].tx_poly      = tx_poly;
        self_check_info->serdes_info[serdes_idx].rx_poly      = rx_poly;

        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_en(lchip, physical_serdes[serdes_idx], DMPS_TX,\
            &tx_lane_en), tx_lane_en);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_en(lchip, physical_serdes[serdes_idx], DMPS_RX,\
            &rx_lane_en), rx_lane_en);
        SELF_CHECK_ERROR_FILTER(sys_tmg_mcu_get_anlt_state(lchip, dport, &anlt_state), anlt_state);
        if(sys_usw_dmps_serdes_get_tx_train_stat(lchip, physical_serdes[serdes_idx], &tx_train_en, &tx_train_stat, NULL) < 0)
        {
            tx_train_en   = SYS_TMG_USELESS_ID8;
            tx_train_stat = SYS_TMG_USELESS_ID8;
        }
        if(sys_usw_dmps_serdes_get_rx_train_stat(lchip, physical_serdes[serdes_idx], &rx_train_en, &rx_train_stat, NULL) < 0)
        {
            rx_train_en   = SYS_TMG_USELESS_ID8;
            rx_train_stat = SYS_TMG_USELESS_ID8;
        }

        self_check_info->serdes_info[serdes_idx].tx_lane_en    = tx_lane_en;
        self_check_info->serdes_info[serdes_idx].rx_lane_en    = rx_lane_en;
        self_check_info->serdes_info[serdes_idx].anlt_state    = (uint8)anlt_state;
        self_check_info->serdes_info[serdes_idx].tx_train_stat = tx_train_en ? tx_train_stat : SYS_PORT_CL72_DISABLE;
        self_check_info->serdes_info[serdes_idx].rx_train_stat = rx_train_en ? rx_train_stat : SYS_PORT_CL72_DISABLE;

        if(sys_usw_dmps_serdes_get_group_fw_version(lchip, SYS_TMG_GET_HSS_ID_BY_SERDES(physical_serdes[serdes_idx]),\
            (void*)&fw_ver) < 0)
        {
            fw_ver.v_major = SYS_TMG_USELESS_ID32;
            fw_ver.v_minor = SYS_TMG_USELESS_ID32;
            fw_ver.v_patch = SYS_TMG_USELESS_ID32;
            fw_ver.v_build = SYS_TMG_USELESS_ID32;
        }
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_fw_stat(lchip, physical_serdes[serdes_idx],\
            &fw_stat), fw_stat);
        /*SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_group_power(lchip, physical_serdes[serdes_idx],\
            &group_power_on), group_power_on);*/
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_power(lchip, physical_serdes[serdes_idx], DMPS_TX,\
            &lane_tx_power_on), lane_tx_power_on);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_power(lchip, physical_serdes[serdes_idx], DMPS_RX,\
            &lane_rx_power_on), lane_rx_power_on);

        self_check_info->serdes_info[serdes_idx].fw_ver.v_major   = fw_ver.v_major;
        self_check_info->serdes_info[serdes_idx].fw_ver.v_minor   = fw_ver.v_minor;
        self_check_info->serdes_info[serdes_idx].fw_ver.v_patch   = fw_ver.v_patch;
        self_check_info->serdes_info[serdes_idx].fw_ver.v_build   = fw_ver.v_build;
        self_check_info->serdes_info[serdes_idx].fw_stat          = fw_stat;
        //self_check_info->serdes_info[serdes_idx].group_power_on   = group_power_on;
        self_check_info->serdes_info[serdes_idx].lane_tx_power_on = lane_tx_power_on;
        self_check_info->serdes_info[serdes_idx].lane_rx_power_on = lane_rx_power_on;

        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_prbs_test_en(lchip, physical_serdes[serdes_idx],\
            DMPS_TX, &tx_prbs_en), tx_prbs_en);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_prbs_test_pattern(lchip, physical_serdes[serdes_idx],\
            DMPS_TX, &tx_prbs_pat), tx_prbs_pat);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_prbs_test_en(lchip, physical_serdes[serdes_idx],\
            DMPS_RX, &rx_prbs_en), rx_prbs_en);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_prbs_test_pattern(lchip, physical_serdes[serdes_idx],\
            DMPS_RX, &rx_prbs_pat), rx_prbs_pat);
        SELF_CHECK_ERROR_FILTER(sys_usw_dmps_serdes_get_lane_prbs_test_cnt(lchip, physical_serdes[serdes_idx],\
            (void*)&prbs), prbs.error_cnt);

        self_check_info->serdes_info[serdes_idx].tx_prbs_en  = tx_prbs_en;
        self_check_info->serdes_info[serdes_idx].tx_prbs_pat = tx_prbs_pat;
        self_check_info->serdes_info[serdes_idx].rx_prbs_en  = rx_prbs_en;
        self_check_info->serdes_info[serdes_idx].rx_prbs_pat = rx_prbs_pat;
        self_check_info->serdes_info[serdes_idx].rx_prbs_cnt = rx_prbs_cnt;

        if(sys_usw_dmps_serdes_get_tx_eq(lchip, physical_serdes[serdes_idx], (void*)&tx_eq) < 0)
        {
            sal_memset(tx_eq.coefficient, 0xff, CTC_CHIP_FFE_PARAM_NUM * sizeof(tx_eq.coefficient[0]));
        }

        self_check_info->serdes_info[serdes_idx].tx_eq.coefficient[0] = tx_eq.coefficient[0];
        self_check_info->serdes_info[serdes_idx].tx_eq.coefficient[1] = tx_eq.coefficient[1];
        self_check_info->serdes_info[serdes_idx].tx_eq.coefficient[2] = tx_eq.coefficient[2];
        self_check_info->serdes_info[serdes_idx].tx_eq.coefficient[3] = tx_eq.coefficient[3];
        self_check_info->serdes_info[serdes_idx].tx_eq.coefficient[4] = tx_eq.coefficient[4];
        self_check_info->serdes_info[serdes_idx].tx_eq.coefficient[5] = tx_eq.coefficient[5];

        if(sys_usw_dmps_serdes_get_rx_ctle(lchip, physical_serdes[serdes_idx], (void*)&rx_ctle) <  0)
        {
            sal_memset(rx_ctle.value, 0xff, CTC_CHIP_CTLE_PARAM_NUM * sizeof(rx_ctle.value[0]));
        }

        self_check_info->serdes_info[serdes_idx].rx_ctle_en       = 1;
        self_check_info->serdes_info[serdes_idx].rx_ctle.value[0] = rx_ctle.value[0];
        self_check_info->serdes_info[serdes_idx].rx_ctle.value[1] = rx_ctle.value[1];
        self_check_info->serdes_info[serdes_idx].rx_ctle.value[2] = rx_ctle.value[2];
    }

    return CTC_E_NONE;
}

int32
sys_tmg_anlt_sm_set_fec(uint8 lchip, uint16 dport, uint32 value)
{
    uint16 lport = sys_usw_dmps_db_get_lport_by_dport(lchip, dport);
    sys_port_api_dmps_info_t port_info = {0};

    SYS_CONDITION_RETURN(lport == SYS_DMPS_INVALID_U16, CTC_E_NONE);

    DP_DEBUG_FUNCTION_CALLED_PRINT();

    CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_info(lchip, lport, &port_info));

    CTC_ERROR_RETURN(_sys_tmg_mac_set_fec(lchip, lport, &port_info, value));

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_cl73_ability_param_check(uint8 lchip, uint16 dport, uint32 ability)
{
    uint32 idx         = 0;
    uint32 unability[] = 
    {
        CTC_PORT_CL73_50GBASE_KR,   CTC_PORT_CL73_50GBASE_CR,   CTC_PORT_CL73_100GBASE_KR2, CTC_PORT_CL73_100GBASE_CR2,
        CTC_PORT_CL73_200GBASE_KR4, CTC_PORT_CL73_200GBASE_CR4, CTC_PORT_CSTM_400GBASE_CR8,
    };

    for (idx = 0; idx < SYS_TMG_MAC_ARRAY_SIZE(unability); idx ++)
    {
        if (ability & unability[idx])
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% cannot support PAM4! \n");
            return CTC_E_INVALID_CONFIG;
        }
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_cl73_ability_hw(uint8 lchip, uint16 dport, sys_dmps_an_ability_t *p_ability)
{
    uint8  psd_num  = 0;
    uint8  lane_idx = 0;
    uint16 psd[DMPS_MAX_NUM_PER_MODULE] = {0};
    uint32 next_page_en  = 1;
    uint32 next_page_num = 0;
    sys_dmps_an_ability_t* cl73_ability = p_ability;
    sys_datapath_an_ability_t old_cl73_ability = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_PSD, &psd_num, psd));

    if((cl73_ability->np1_ability0) || (cl73_ability->np1_ability1))
    {
        next_page_num = 2;
    }

    /* 3.1 read old ability*/
    for(lane_idx = 0; lane_idx < psd_num; lane_idx ++)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_BASE_PAGE_31_0), &old_cl73_ability.base_ability0));
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_BASE_PAGE_47_32), &old_cl73_ability.base_ability1));
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_NEXT_PAGE_TX1_31_0), &old_cl73_ability.np1_ability0));
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_read_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_NEXT_PAGE_TX1_47_32), &old_cl73_ability.np1_ability1));
    }

    /* 3.2 clear old ability*/
    old_cl73_ability.base_ability0 &= 0x001F73FF;
    old_cl73_ability.base_ability1 &= 0xFFFF0000;
    old_cl73_ability.np1_ability0  &= 0x0000FFFF;
    old_cl73_ability.np1_ability1  &= 0xFFFF0000;

    /* 3.3 cfg new ability*/
    cl73_ability->base_ability0     |= old_cl73_ability.base_ability0;
    cl73_ability->base_ability1     |= old_cl73_ability.base_ability1;
    cl73_ability->np1_ability0      |= old_cl73_ability.np1_ability0;
    cl73_ability->np1_ability1      |= old_cl73_ability.np1_ability1;

    for(lane_idx = 0; lane_idx < psd_num; lane_idx ++)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_write_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_BASE_PAGE_31_0), cl73_ability->base_ability0));
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_write_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_BASE_PAGE_47_32), cl73_ability->base_ability1 & 0xffff));
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_write_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_NEXT_PAGE_TX1_31_0), cl73_ability->np1_ability0));
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_write_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_NEXT_PAGE_TX1_47_32), cl73_ability->np1_ability1 & 0xffff));
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_write_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_AUTO_NEXT_PAGE_EN), next_page_en));
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_write_field(lchip, psd[lane_idx], TMG_CL73_REG_STR(TMG_CL73_NEXT_PAGE_NUM), next_page_num));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_port_cl73_ability(uint8 lchip, uint16 dport, void* p_ability)
{
    sys_dmps_an_ability_t* cl73_ability = p_ability;
    sys_dmps_db_upt_info_t upt_info_p  = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_set_cl73_ability_hw(lchip, dport, cl73_ability));

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
    DMPS_DB_SET_MAP_INFO(upt_info_p,      DMPS_DB_DPORT,         dport);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_BP_ABILITY0,  cl73_ability->base_ability0);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_BP_ABILITY1,  cl73_ability->base_ability1);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_NP0_ABILITY0, cl73_ability->np0_ability0);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_NP0_ABILITY1, cl73_ability->np0_ability1);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_NP1_ABILITY0, cl73_ability->np1_ability0);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_NP1_ABILITY1, cl73_ability->np1_ability1);

    CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &upt_info_p));
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_cl73_ability(uint8 lchip, uint16 dport, uint32 ctc_ability)
{
    uint8  is_hit     = FALSE;
    uint32 loop_idx   = 0;
    sys_dmps_an_ability_t cl73_ability = {0};
    cl73_ability_ctc_sys_map_tbl_t ability_map_tab[] = 
    {
        /* ctc_cl73_ability                       sys_cl73_ability                                         pointer of cfg_val        */
        {CTC_PORT_CL73_10GBASE_KR,                SYS_PORT_CL73_10GBASE_KR,                                &cl73_ability.base_ability0},

        {CTC_PORT_CL73_25GBASE_CR,                SYS_PORT_CL73_25GBASE_CR,                                &cl73_ability.base_ability0},
        {CTC_PORT_CL73_25GBASE_CRS,               SYS_PORT_CL73_25GBASE_CR_S,                              &cl73_ability.base_ability0},
        {CTC_PORT_CL73_25GBASE_KR,                (SYS_PORT_CL73_25GBASE_KR | SYS_PORT_CL73_25GBASE_KR_S), &cl73_ability.base_ability0},
        {CTC_PORT_CL73_25GBASE_KRS,               SYS_PORT_CL73_25GBASE_KR_S,                              &cl73_ability.base_ability0},
        {CTC_PORT_CSTM_25GBASE_KR1,               SYS_PORT_CSTM_25GBASE_KR1,                               &cl73_ability.np1_ability0},
        {CTC_PORT_CSTM_25GBASE_CR1,               SYS_PORT_CSTM_25GBASE_CR1,                               &cl73_ability.np1_ability0},
        {CTC_PORT_CL73_25G_RS_FEC_REQUESTED,      SYS_PORT_CL73_25G_RS_FEC_REQ,                            &cl73_ability.base_ability1},
        {CTC_PORT_CL73_25G_BASER_FEC_REQUESTED,   SYS_PORT_CL73_25G_BASER_FEC_REQ,                         &cl73_ability.base_ability1},

        {CTC_PORT_CL73_40GBASE_KR4,               SYS_PORT_CL73_40GBASE_KR4,                               &cl73_ability.base_ability0},
        {CTC_PORT_CL73_40GBASE_CR4,               SYS_PORT_CL73_40GBASE_CR4,                               &cl73_ability.base_ability0},

        {CTC_PORT_CL73_50GBASE_KR,                SYS_PORT_CL73_50GBASE_KR,                                &cl73_ability.base_ability1},
        {CTC_PORT_CL73_50GBASE_CR,                SYS_PORT_CL73_50GBASE_CR,                                &cl73_ability.base_ability1},
        {CTC_PORT_CSTM_50GBASE_KR2,               SYS_PORT_CSTM_50GBASE_KR2,                               &cl73_ability.np1_ability0},
        {CTC_PORT_CSTM_50GBASE_CR2,               SYS_PORT_CSTM_50GBASE_CR2,                               &cl73_ability.np1_ability0},

        {CTC_PORT_CL73_100GBASE_KR4,              SYS_PORT_CL73_100GBASE_KR4,                              &cl73_ability.base_ability0},
        {CTC_PORT_CL73_100GBASE_CR4,              SYS_PORT_CL73_100GBASE_CR4,                              &cl73_ability.base_ability0},

        {CTC_PORT_CL73_FEC_ABILITY,               SYS_PORT_CL73_FEC_SUP,                                   &cl73_ability.base_ability1},
        {CTC_PORT_CL73_FEC_REQUESTED,             SYS_PORT_CL73_FEC_REQ,                                   &cl73_ability.base_ability1},

        {CTC_PORT_CSTM_RS_FEC_ABILITY ,           SYS_PORT_CSTM_CL91_FEC_SUP,                              &cl73_ability.np1_ability1},
        {CTC_PORT_CSTM_RS_FEC_REQUESTED,          SYS_PORT_CSTM_CL91_FEC_REQ,                              &cl73_ability.np1_ability1},

        {CTC_PORT_CSTM_BASER_FEC_ABILITY,         SYS_PORT_CSTM_CL74_FEC_SUP,                              &cl73_ability.np1_ability1},
        {CTC_PORT_CSTM_BASER_FEC_REQUESTED,       SYS_PORT_CSTM_CL74_FEC_REQ,                              &cl73_ability.np1_ability1},
    }; 
    sys_dmps_db_upt_info_t upt_info_p  = {0};
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    SYS_MAC_INIT_CHECK();

    /* ctc_cl73_ability --> sys_cl73_ability */
    if (0x0 != ctc_ability)
    {    
        /* param check */
        CTC_ERROR_RETURN(_sys_tmg_mac_set_cl73_ability_param_check(lchip, dport, ctc_ability));

        /* get old cl73_ability */
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
        DMPS_DB_SET_MAP_INFO(upt_info_p,        DMPS_DB_DPORT,         dport);
        DMPS_DB_SET_PROPERTY_UPDATE(upt_info_p, DMPS_DB_PORT_BP_ABILITY0);
        DMPS_DB_SET_PROPERTY_UPDATE(upt_info_p, DMPS_DB_PORT_BP_ABILITY1);
        DMPS_DB_SET_PROPERTY_UPDATE(upt_info_p, DMPS_DB_PORT_NP0_ABILITY0);
        DMPS_DB_SET_PROPERTY_UPDATE(upt_info_p, DMPS_DB_PORT_NP0_ABILITY1);
        DMPS_DB_SET_PROPERTY_UPDATE(upt_info_p, DMPS_DB_PORT_NP1_ABILITY0);
        DMPS_DB_SET_PROPERTY_UPDATE(upt_info_p, DMPS_DB_PORT_NP1_ABILITY1);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &upt_info_p));
        DMPS_DB_GET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_BP_ABILITY0,  cl73_ability.base_ability0);
        DMPS_DB_GET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_BP_ABILITY1,  cl73_ability.base_ability1);
        DMPS_DB_GET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_NP0_ABILITY0, cl73_ability.np0_ability0);
        DMPS_DB_GET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_NP0_ABILITY1, cl73_ability.np0_ability1);
        DMPS_DB_GET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_NP1_ABILITY0, cl73_ability.np1_ability0);
        DMPS_DB_GET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_NP1_ABILITY1, cl73_ability.np1_ability1);

        /* clear old ability-ext */
        for (loop_idx = 0; loop_idx < SYS_TMG_MAC_ARRAY_SIZE(ability_map_tab); loop_idx ++)
        {
            *ability_map_tab[loop_idx].p_ability &= (~ability_map_tab[loop_idx].sys_ability);
        }

        for (loop_idx = 0; loop_idx < SYS_TMG_MAC_ARRAY_SIZE(ability_map_tab); loop_idx ++)
        {
            /* if ctc_cl73_ability cfg a certain ability, then set a bit of cfg_val by sys_cl73_ability */
            if (ctc_ability & ability_map_tab[loop_idx].ctc_ability)
            {
                is_hit = TRUE;
                *ability_map_tab[loop_idx].p_ability |= ability_map_tab[loop_idx].sys_ability;
            }
        }
        if (!is_hit)
        {
            return CTC_E_INVALID_PARAM;
        }

        if((cl73_ability.np1_ability0) || (cl73_ability.np1_ability1))
        {
            cl73_ability.base_ability0 |= (SYS_PORT_CL73_NEXT_PAGE);
        }
    }

    /* 2. cfg ability */
    CTC_ERROR_RETURN(_sys_tmg_mac_set_port_cl73_ability(lchip, dport, (void*)(&cl73_ability)));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_rx_pmac_sfd_en(uint8 lchip, uint16 lport, uint32 value)
{
    uint16 dport                = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, value %u\n", __FUNCTION__, lchip, dport, value);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_RX_PMAC_SFD_EN, lchip, &api_db, value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_tx_pmac_sfd_en(uint8 lchip, uint16 lport, uint32 value)
{
    uint16 dport                = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    sys_dmps_mac_api_db_t   api_db      = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s: lchip %u, dport %u, value %u\n", __FUNCTION__, lchip, dport, value);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));

    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_TX_PMAC_SFD_EN, lchip, &api_db, value);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_xpipe_en(uint8 lchip, uint16 lport, uint32 value, uint8 dir)
{
    uint8  chan_num = 0;
    uint16 dport    = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    uint16 chan_list[DMPS_MAX_NUM_PER_MODULE] = {0};

    CTC_ERROR_RETURN(_sys_tmg_mac_set_xpipe_db(lchip, lport, value, dir));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport,
                                                        GET_CHAN_TYPE_BY_DIR(dir), &chan_num, chan_list));
    CTC_ERROR_RETURN(_sys_tmg_datapath_xpipe_resource_alloc(lchip, dport, chan_num, chan_list, dir));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_xpipe_db(uint8 lchip, uint16 lport, uint32 value, uint8 dir)
{
    uint8  cnt           = 0;
    uint8  free_chan_num = 0;
    uint8  dp_id         = 0;
    uint8  txqm_id       = 0;
    uint8  xpipe_en      = 0;
    uint8  xpipe_status  = 0;
    uint8  speed_mode    = 0;
    uint8  chan_num      = 0;
    uint8  inverse_dir   = CHAN_DIR_IS_TX(dir) ? CHAN_DIR_RX : CHAN_DIR_TX;
    uint8  sub_chan[TMG_MAX_XPIPE_CHAN]        = {0};
    uint8  mac_client[TMG_MAX_XPIPE_CHAN]      = {0};
    uint16 chan[TMG_MAX_XPIPE_CHAN+1]            = {0};
    uint16 chan_id                            = 0;
    uint16 p_mac_client_id                    = 0;
    uint16 dport                              = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
    uint16 chan_list[DMPS_MAX_NUM_PER_MODULE] = {0};
    sys_dmps_change_chan_info_t info          = {0};
    sys_dmps_db_upt_info_t port_info          = {0};
    sys_dmps_db_upt_info_t upt_info_p         = {0};
    ctc_register_xpipe_mode_t mode            = (ctc_register_xpipe_mode_t) value;
    sys_dmps_db_chan_info_t p_chan_info[TMG_MAX_XPIPE_CHAN] = {{0}};

    CTC_ERROR_RETURN(sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, dport));

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_XPIPE_EN);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_DP_ID_BY_DIR(dir));
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_TXQM_ID_BY_DIR(dir));
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SPEED_MODE_BY_DIR(dir));
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir));
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SUB_CHAN_ID_BY_DIR(dir));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, GET_DP_ID_BY_DIR(dir),      dp_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, GET_TXQM_ID_BY_DIR(dir),    txqm_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SPEED_MODE_BY_DIR(dir), speed_mode);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_XPIPE_EN,      xpipe_status);

    xpipe_en = (CTC_XPIPE_MODE_0 == mode) ? FALSE : TRUE;
    /* (tx disable -> tx enable) | (rx disable -> rx enable) */
    if (xpipe_en)
    {
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan[0]);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SUB_CHAN_ID_BY_DIR(dir),   sub_chan[0]);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir), mac_client[0]);

        /* chan_num = 1 if mode is CTC_XPIPE_MODE_1 or CTC_XPIPE_MODE_2 or CTC_XPIPE_MODE_2, otherwise, chan_num = 2 */
        free_chan_num = ((CTC_XPIPE_MODE_1 == mode) || (CTC_XPIPE_MODE_2 == mode) || (CTC_XPIPE_MODE_3 == mode)) ? 1 : 2;
        /* get free chan and mac client */
        CTC_ERROR_RETURN(_sys_tmg_datapath_get_free_chan(lchip, dport, free_chan_num, chan + 1, sub_chan + 1, mac_client + 1, dir));

        /* config new channel for checking validity */
        for (cnt = 1; cnt < free_chan_num + 1; cnt++)
        {
            SYS_CONDITION_RETURN(DMPS_MAX_CHAN_NUM <= chan[cnt], CTC_E_INVALID_CONFIG);
            (void) sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p);
            DMPS_DB_SET_MAP_INFO(upt_info_p, GET_CHAN_ID_BY_DIR(dir),            chan[cnt]);
            DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_DP_ID_BY_DIR(dir),         dp_id);
            DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_TXQM_ID_BY_DIR(dir),       txqm_id);
            DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_SPEED_MODE_BY_DIR(dir),    speed_mode);
            DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_MAC_CLIENT_ID_BY_DIR(dir), mac_client[cnt]);
            DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_SUB_CHAN_ID_BY_DIR(dir),   sub_chan[cnt]);
            (void) sys_usw_dmps_db_set_port_info(lchip, &upt_info_p);
        }

        /* check validity */
        info.dst_speed_mode   = speed_mode;
        info.dst_chan_num     = free_chan_num;
        info.dst_chan_list[0] = chan[1];
        info.dst_chan_list[1] = chan[2];
        CTC_ERROR_RETURN(_sys_tmg_datapath_check(lchip, dp_id, txqm_id, &info, dir, FALSE));

        /* Update DMPS_DB */
        for (cnt = 0; cnt < free_chan_num + 1; cnt++)
        {
            /* Tx: reverse chan to mac client,  Rx: not reverse */
            p_mac_client_id = CHAN_DIR_IS_TX(dir) ? mac_client[free_chan_num - cnt] : mac_client[cnt];
            SYS_CONDITION_RETURN(DMPS_MAX_CHAN_NUM <= chan[cnt], CTC_E_INVALID_CONFIG);
            (void) sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p);
            DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_DPORT,                      dport);
            DMPS_DB_SET_MAP_INFO(upt_info_p, GET_CHAN_ID_BY_DIR(dir),            chan[cnt]);
            DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_XPIPE_EN,         xpipe_status | dir);
            DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_MAC_CLIENT_ID_BY_DIR(dir), p_mac_client_id);
            if (0 != cnt)
            {
                /* opf: Assign new channel */
                CTC_ERROR_RETURN(sys_usw_dmps_db_assign_chan_by_dir(lchip, chan[cnt], dir));
                /* Add mapping between port and new channel */
                DMPS_DB_SET_MAP_UPDATE(upt_info_p);
            }
            (void) sys_usw_dmps_db_set_port_info(lchip, &upt_info_p);
        }
    }
    /* (tx enable -> tx disable) | (rx enable -> rx disable) */
    else
    {
        /* get chan_list */
        sal_memset(chan_list, DMPS_INVALID_VALUE_U8, DMPS_MAX_NUM_PER_MODULE * sizeof(uint16));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport,
            GET_CHAN_TYPE_BY_DIR(dir), &chan_num, chan_list));
        if (1 == chan_num)
        {
            return CTC_E_NONE;
        }
        else if ((0 == chan_num) || (chan_num > TMG_MAX_XPIPE_CHAN))
        {
            return CTC_E_INVALID_CONFIG;
        }

        /* get chan_info list */
        for (cnt = 0; cnt < chan_num; cnt++)
        {
            chan_id = chan_list[cnt];
            SYS_CONDITION_RETURN(DMPS_MAX_CHAN_NUM <= chan_id, CTC_E_INVALID_CONFIG);
            p_chan_info[cnt].chan_id = chan_id;
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_chan_info(lchip, p_chan_info + cnt, dir));
        }

        /* tx: reverse mac_client */
        if (CHAN_DIR_IS_TX(dir))
        {
            p_mac_client_id                         = p_chan_info[0].mac_client_id;
            p_chan_info[0].mac_client_id            = p_chan_info[chan_num - 1].mac_client_id;
            p_chan_info[chan_num - 1].mac_client_id = p_mac_client_id;
        }

        for (cnt = 0; cnt < chan_num; cnt++)
        {
            /* update port and chan property */
            (void) sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p);
            DMPS_DB_SET_MAP_INFO(upt_info_p,      DMPS_DB_DPORT,         dport);
            DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_XPIPE_EN, (CHAN_DIR_IS_TXRX(xpipe_status) ? inverse_dir : 0));
            if (0 == cnt)
            {
                DMPS_DB_SET_MAP_INFO(upt_info_p,      GET_CHAN_ID_BY_DIR(dir),       p_chan_info[cnt].chan_id);
                DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_MAC_CLIENT_ID_BY_DIR(dir), p_chan_info[cnt].mac_client_id);
                (void) sys_usw_dmps_db_set_port_info(lchip, &upt_info_p);

                CTC_ERROR_RETURN(_sys_tmg_datapath_resource_alloc_chan(lchip, chan_list[cnt], TRUE, dir, TRUE));
            }
            else
            {
                DMPS_DB_SET_MAP_INFO(upt_info_p,      GET_CHAN_ID_BY_DIR(dir),       p_chan_info[cnt].chan_id);
                DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_SPEED_MODE_BY_DIR(dir),    SYS_PORT_SPEED_MAX);
                DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_MAC_CLIENT_ID_BY_DIR(dir), p_chan_info[cnt].mac_client_id);
                (void) sys_usw_dmps_db_set_port_info(lchip, &upt_info_p);

                CTC_ERROR_RETURN(_sys_tmg_datapath_resource_alloc_chan(lchip, chan_list[cnt], FALSE, dir, TRUE));

                (void) sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p);
                DMPS_DB_SET_MAP_INFO(upt_info_p,      GET_CHAN_ID_BY_DIR(dir),       p_chan_info[cnt].chan_id);
                DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_DP_ID_BY_DIR(dir),         DMPS_INVALID_VALUE_U8);
                DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_TXQM_ID_BY_DIR(dir),       DMPS_INVALID_VALUE_U8);
                DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_MAC_CLIENT_ID_BY_DIR(dir), DMPS_INVALID_VALUE_U16);
                DMPS_DB_SET_PROPERTY_INFO(upt_info_p, GET_SUB_CHAN_ID_BY_DIR(dir),   DMPS_INVALID_VALUE_U16);
                (void) sys_usw_dmps_db_set_port_info(lchip, &upt_info_p);
            }
#if 0 
            /* clear DsQMgrDeqScanBmp */
            CTC_ERROR_RETURN(_sys_at_datapath_set_qmgr_deq_scan_bmp(lchip, core_id, pp_id,
                dp_id * SYS_AT_CHAN_NUM_PER_DP + p_chan_info[cnt].sub_chan_id, 0));
#endif
            if (0 != cnt)
            {
                /* update mapping */
                (void) sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p);
                DMPS_DB_SET_MAP_UPDATE(upt_info_p);
                DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_DPORT,           dport);
                DMPS_DB_SET_MAP_INFO(upt_info_p, GET_OLD_CHAN_ID_BY_DIR(dir), p_chan_info[cnt].chan_id);
                (void) sys_usw_dmps_db_set_port_info(lchip, &upt_info_p);

                CTC_ERROR_RETURN(sys_usw_dmps_db_free_chan_by_dir(lchip, p_chan_info[cnt].chan_id, dir));
            }
        }
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_reset_sgmac_rx_buffer(uint8 lchip, uint16 dport, uint8 enable)
{
    uint32 cmd    = 0;
    uint32 tbl_id = QuadSgmacReserved_t;
    uint32 fld_id = QuadSgmacReserved_reserved_f;
    uint32 value  = 0;
    uint32 index  = 0;
    sys_dmps_db_upt_info_t port_info = {0};
    sys_dmps_mac_api_db_t  api_db    = {0};
    QuadSgmacReserved_m mac_rsv;

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));

    index = DRV_INS(api_db.mac_grp_idx, 0);
    cmd   = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_rsv));
    DRV_IOR_FIELD(lchip, tbl_id, fld_id, &value, &mac_rsv);
    if(enable)
    {
        value |= (1 << api_db.mac_idx);
    }
    else
    {
        value &= (~(1 << api_db.mac_idx));
    }
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &value, &mac_rsv, api_db.mac_grp_idx, 0);
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &mac_rsv));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_rx_en(uint8 lchip, uint16 dport, uint8 enable)
{
    uint16 mac_id = 0;
    uint16 lport  = sys_usw_dmps_db_get_lport_by_dport(lchip, dport);
    sys_dmps_db_upt_info_t port_info = {0};
    sys_dmps_mac_api_db_t  api_db    = {0};
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_mac_id(lchip, lport, &mac_id));

    if (1 != SDK_WORK_PLATFORM)
    {
        /* FEC/PCS/MII reset or release */
        if(enable)
        {
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MAC_RX_EN, lchip, &api_db, 1);
        }
        else
        {
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_MAC_RX_EN, lchip, &api_db, 0);
            CTC_ERROR_RETURN(_sys_tmg_mac_reset_sgmac_rx_buffer(lchip, dport, 1));
            CTC_ERROR_RETURN(_sys_tmg_mac_reset_sgmac_rx_buffer(lchip, dport, 0));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_pcs_rst(uint8 lchip, uint16 dport, uint8 dir, uint8 reset)
{
    sys_dmps_db_upt_info_t port_info = {0};
    sys_dmps_mac_api_db_t  api_db    = {0};

    SYS_MAC_INIT_CHECK();

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, &port_info, &api_db));

    if(reset)
    {
        if(DMPS_RX == dir)
        {
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FEC_RST, lchip, &api_db, (uint32)dir, (uint32)reset);
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_PCS_RST, lchip, &api_db, (uint32)dir, (uint32)reset);
        }
        else
        {
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_PCS_RST, lchip, &api_db, (uint32)dir, (uint32)reset);
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FEC_RST, lchip, &api_db, (uint32)dir, (uint32)reset);
        }
    }
    else
    {
        if(DMPS_RX == dir)
        {
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_PCS_RST, lchip, &api_db, (uint32)dir, (uint32)reset);
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FEC_RST, lchip, &api_db, (uint32)dir, (uint32)reset);
        }
        else
        {
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_FEC_RST, lchip, &api_db, (uint32)dir, (uint32)reset);
            DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_SET_PCS_RST, lchip, &api_db, (uint32)dir, (uint32)reset);
        }
    }
    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_rx_rst_condition(uint8 lchip, uint16 dport, uint8 rst_cond)
{
    sys_dmps_db_upt_info_t port_info = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PCS_IDX);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_IDX);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_GROUP_ID);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_LINK_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_MAC_EN);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));

    SYS_CONDITION_RETURN(0 == port_info.mac_en, CTC_E_NONE);

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "        set_rx_rst: dport %u, rst_cond %u\n", dport, rst_cond);

    switch(rst_cond)
    {
        case RST_PCS_0_MAC_1:
            /*1. set all rx reset*/
            CTC_ERROR_RETURN(_sys_tmg_mac_set_rx_en(lchip, dport, 0));
            /*2. release pcs rx reset*/
            CTC_ERROR_RETURN(_sys_tmg_mac_set_pcs_rst(lchip, dport, DMPS_RX, 0));
            break;
        case RST_PCS_0_MAC_0:
        default:
            /*1. set pcs rx reset*/
            CTC_ERROR_RETURN(_sys_tmg_mac_set_pcs_rst(lchip, dport, DMPS_RX, 1));
            /*2. release all rx reset*/
            CTC_ERROR_RETURN(_sys_tmg_mac_set_rx_en(lchip, dport, 1));
            break;
    }
    return CTC_E_NONE; 
}

int32
_sys_tmg_mac_set_link_mode(uint8 lchip, uint16 dport, uint32 link_mode)
{
    uint32 cur_link_mode = 0;
    SYS_CONDITION_RETURN(LINK_MODE_BUTT <= link_mode, CTC_E_INVALID_PARAM);

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode_by_dport(lchip, dport, &cur_link_mode));
    SYS_CONDITION_RETURN(cur_link_mode == link_mode, CTC_E_NONE);

    CTC_ERROR_RETURN(_sys_tmg_mac_set_rx_rst_condition(lchip, dport, 
        (LINK_MODE_STDALONE == link_mode) ? RST_PCS_0_MAC_0 : RST_PCS_0_MAC_1));

    CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_mode_by_dport(lchip, dport, link_mode));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_signal_detect(uint8 lchip, void* p_psd, uint8* p_sigdet)
{
    uint8 sigdet = 1;
    uint8 sd_lane = 0;
    uint8 idx;
    sys_usw_dmps_serdes_id_t* psd = (sys_usw_dmps_serdes_id_t*)p_psd;

    for(idx = 0; idx < psd->num; idx++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_serdes_get_rx_sigdet(lchip, psd->serdes[idx], &sd_lane));
        if(0 == sd_lane)
        {
            sigdet = 0;
            break;
        }
    }
    *p_sigdet = sigdet;

    return CTC_E_NONE;
}

/*
RX_NO_SIGNAL: at least 1 lane sigdet = 0
RX_INVALID_SIGNAL: at least 1 lane CDR = 0, and all lane sigdet = 1
RX_VALID_SIGNAL: all lane CDR = 1
*/
int32
_sys_tmg_mac_get_signal_valid(uint8 lchip, void* p_psd, uint8* p_sig_vld)
{
    uint8  sig_vld  = RX_VALID_SIGNAL;
    uint8  sd_lane  = 0;
    uint8  sd_force = 0;
#ifndef EMULATION_ENV
    uint8  cdr_lane = 0;
#endif
    uint8  idx;
    sys_usw_dmps_serdes_id_t* psd = (sys_usw_dmps_serdes_id_t*)p_psd;

    for(idx = 0; idx < psd->num; idx++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_serdes_get_rx_force_sigdet(lchip, psd->serdes[idx], &sd_force, NULL));
        CTC_ERROR_RETURN(sys_usw_dmps_serdes_get_rx_sigdet(lchip, psd->serdes[idx], &sd_lane));

        sd_lane = sd_lane | sd_force;

#ifndef EMULATION_ENV
        if(0 != sd_lane)
        {
            CTC_ERROR_RETURN(sys_usw_dmps_serdes_get_rx_cdr_lock(lchip, psd->serdes[idx], &cdr_lane));
            if(0 == cdr_lane)
            {
                sig_vld = RX_INVALID_SIGNAL;
            }
        }
        else
        {
            sig_vld = RX_NO_SIGNAL;
            break;
        }
#else
        if(!SYS_TMG_PSD_WITH_HSS32G_MODULE(psd->serdes[idx]))
        {
            continue;
        }
        if(0 == sd_lane)
        {
            sig_vld = RX_NO_SIGNAL;
        }
#endif
    }
    *p_sig_vld = sig_vld;

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_set_port_rx_train_en(uint8 lchip, void* p_psd, uint8 en)
{
    uint8 idx;
    sys_usw_dmps_serdes_id_t* psd = (sys_usw_dmps_serdes_id_t*)p_psd;

    for(idx = 0; idx < psd->num; idx++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_serdes_set_rx_train_en(lchip, psd->serdes[idx], en ? 1 : 0));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_port_rx_train_stat(uint8 lchip, void* p_psd, uint8* p_stat)
{
#ifndef EMULATION_ENV
    uint8 idx;
    uint8 stat = 0;
    uint8 en_lane = 1;
    uint8 stat_lane = 1;
    uint32 en = 1;
    sys_usw_dmps_serdes_id_t* psd = (sys_usw_dmps_serdes_id_t*)p_psd;

    CTC_BIT_SET(stat, SYS_PORT_CL72_OK);

    for(idx = 0; idx < psd->num; idx++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_serdes_get_rx_train_stat(lchip, psd->serdes[idx], &en_lane, &stat_lane, NULL));
        if(0 == en_lane)
        {
            en = 0;
        }
        if(SYS_PORT_CL72_DISABLE == stat_lane)
        {
            CTC_BIT_SET(stat, SYS_PORT_CL72_DISABLE);
        }
        else if(SYS_PORT_CL72_PROGRESS == stat_lane)
        {
            CTC_BIT_SET(stat, SYS_PORT_CL72_PROGRESS);
        }
        else if(SYS_PORT_CL72_FAIL == stat_lane)
        {
            CTC_BIT_SET(stat, SYS_PORT_CL72_FAIL);
        }
    }
    
    if((0 == en) || CTC_IS_BIT_SET(stat, SYS_PORT_CL72_DISABLE))
    {
        *p_stat = RX_TRAIN_STOP;
    }
    else if(CTC_IS_BIT_SET(stat, SYS_PORT_CL72_FAIL))
    {
        *p_stat = RX_TRAIN_FAIL;
    }
    else if(CTC_IS_BIT_SET(stat, SYS_PORT_CL72_PROGRESS))
    {
        *p_stat = RX_TRAIN_RUN;
    }
    else
    {
        *p_stat = RX_TRAIN_SUCCESS;
    }
#else
    *p_stat = RX_TRAIN_SUCCESS;
#endif

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_prbs_rx_en(uint8 lchip, void* p_psd, uint32* p_prbs_en)
{
    uint8  idx     = 0;
    uint8  en_lane = 0;
    uint32 en      = 0;
    sys_usw_dmps_serdes_id_t* psd = (sys_usw_dmps_serdes_id_t*)p_psd;

    SYS_CONDITION_RETURN(NULL == psd, CTC_E_INVALID_PTR);

    for(idx = 0; idx < psd->num; idx++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_serdes_get_lane_prbs_test_en(lchip, psd->serdes[idx], DMPS_RX, &en_lane));
        if(en_lane)
        {
            en = 1;
            break;
        }
    }
    SYS_USW_VALID_PTR_WRITE(p_prbs_en, en);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_get_loopback_mode(uint8 lchip, void* p_psd, uint32* p_lpbk_mode)
{
    uint8  idx       = 0;
    uint32 mode_lane = DMPS_SERDES_LPBK_NONE;
    uint32 mode      = DMPS_SERDES_LPBK_NONE;
    ctc_chip_serdes_loopback_t lpbk = {0};
    sys_usw_dmps_serdes_id_t* psd = (sys_usw_dmps_serdes_id_t*)p_psd;

    SYS_CONDITION_RETURN(NULL == psd, CTC_E_INVALID_PTR);

    for(mode_lane = DMPS_SERDES_LPBK_INTERNAL; mode_lane < DMPS_SERDES_LPBK_NONE; mode_lane++)
    {
        lpbk.mode = mode_lane;
        for(idx = 0; idx < psd->num; idx++)
        {
            lpbk.serdes_id = psd->serdes[idx];
            sys_usw_dmps_serdes_get_lane_loopback(lchip, lpbk.serdes_id, (void*)(&lpbk));
            if(lpbk.enable)
            {
                mode = mode_lane;
                break;
            }
        }
        SYS_CONDITION_BREAK(mode != DMPS_SERDES_LPBK_NONE);
    }
    SYS_USW_VALID_PTR_WRITE(p_lpbk_mode, mode);
    return CTC_E_NONE;
}


int32
_sys_tmg_mac_link_fsm_nonready_proc(uint8 lchip, uint16 lport)
{
    uint32 link_mode = LINK_MODE_PCS_PMA;
    uint32 an_en     = 0;
    uint32 mac_en    = 0;
    uint16 dport     = 0;
    uint8  sig_vld   = 0;
    uint32 pcs_up    = 0;
    uint32 prbs_en   = 0;
    uint32 lpbk      = 0;
    sys_usw_dmps_serdes_id_t psd = {{0}};

    /*0. judge standalone mode and jump to PMA_RX_COVER*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode(lchip, lport, &link_mode));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_en(lchip, lport, &an_en));
    if((LINK_MODE_STDALONE == link_mode) || (1 == an_en))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_NONREADY: (lport %u, link_mode %u, an_en %u) go to PMA_RX_COVER\n", 
            lport, link_mode, an_en);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_0, 
            ((uint16)((link_mode << 8) & 0xff00) | (uint16)(an_en & 0x00ff)));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_COVER));
        return CTC_E_NONE;
    }

    /*1. judge if mac disable*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_mac_en(lchip, lport, &mac_en));
    if(!mac_en)
    {
        return CTC_E_NONE;
    }

    /*1.1 judge if prbs test enable, stay in current STATE*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_by_lport(lchip, lport, psd.serdes, &(psd.num)));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_prbs_rx_en(lchip, (void*)(&psd), &prbs_en));
    if(prbs_en)
    {
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_1, (uint16)prbs_en);
        return CTC_E_NONE;
    }

    /*1.2 judge if loopback enable, jump to STATE PCS_SYNC*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_loopback_mode(lchip, (void*)(&psd), &lpbk));
    if(DMPS_SERDES_LPBK_LOCAL == lpbk)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_NONREADY: (lport %u, lpbk %u) go to PMA_RX_PCS_SYNC1\n", 
            lport, lpbk);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_2, (uint16)lpbk);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_PCS_SYNC1));
        return CTC_E_NONE;
    }

    /*2. judge signal valid*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_signal_valid(lchip, (void*)(&psd), &sig_vld));
    if(RX_NO_SIGNAL == sig_vld)
    {
        /*optional PMA recovery*/
        return CTC_E_NONE;
    }

    /*3. judge pcs_up to start pre train, or directly jump to post train*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_pcs_link_status(lchip, dport, &pcs_up));
#ifdef EMULATION_ENV
        /*force SerDes:0~15,32~79 which connect with Macshim pcs_up*/
        if(!SYS_TMG_PSD_WITH_HSS32G_MODULE(psd.serdes[0]))
        {
            pcs_up = 1;
        }
#endif
    if(pcs_up)
    {
        /*enable rx train*/
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_NONREADY: (lport %u, pcs_up %u) enable POST_TRAIN then go to PMA_RX_POST_TRAIN1\n", 
            lport, pcs_up);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_3, (uint16)pcs_up);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), TRUE));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_POST_TRAIN1));
    }
    else
    {
        /*enable init train*/
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_NONREADY: (lport %u, pcs_up %u) enable PRE_TRAIN then go to PMA_RX_PRE_TRAIN1\n", 
            lport, pcs_up);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_4, (uint16)pcs_up);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), TRUE));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_PRE_TRAIN1));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_link_fsm_pretrain_proc(uint8 lchip, uint16 lport, uint32 fsm)
{
    uint32 link_mode  = LINK_MODE_PCS_PMA;
    uint32 an_en      = 0;
    uint32 mac_en     = 0;
    uint8  train_stat = 0;
    uint32 prbs_en    = 0;
    uint32 lpbk       = 0;
    sys_usw_dmps_serdes_id_t psd = {{0}};

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_by_lport(lchip, lport, psd.serdes, &(psd.num)));

    /*0. judge standalone mode and jump to PMA_RX_COVER*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode(lchip, lport, &link_mode));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_en(lchip, lport, &an_en));
    if((LINK_MODE_STDALONE == link_mode) || (1 == an_en))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PRE_TRAIN: (lport %u, link_mode %u, an_en %u, fsm %u) go to PMA_RX_COVER\n", 
            lport, link_mode, an_en, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_5, 
            ((uint16)((link_mode << 8) & 0xff00) | (uint16)(an_en & 0x00ff)));
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_COVER));
        return CTC_E_NONE;
    }

    /*1. judge if mac disable*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_mac_en(lchip, lport, &mac_en));
    if(!mac_en)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PRE_TRAIN: (lport %u, mac_en %u) disable PRE_TRAIN then go to PMA_RX_NONREADY\n", 
            lport, mac_en);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_6, (uint16)mac_en);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
        /*optional PMA recovery*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        return CTC_E_NONE;
    }

    /*1.1 judge if prbs test enable, stay in current STATE*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_prbs_rx_en(lchip, (void*)(&psd), &prbs_en));
    if(prbs_en)
    {
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_1, (uint16)prbs_en);
        return CTC_E_NONE;
    }

    /*1.2 judge if loopback enable, disable PRE_TRAIN and jump to STATE PCS_SYNC*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_loopback_mode(lchip, (void*)(&psd), &lpbk));
    if(DMPS_SERDES_LPBK_LOCAL == lpbk)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PRE_TRAIN: (lport %u, lpbk %u, fsm %u) disable PRE_TRAIN then go to PMA_RX_PCS_SYNC\n", 
            lport, lpbk, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_7, (uint16)lpbk);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_PCS_SYNC1));
        return CTC_E_NONE;
    }

    /*2. judge pre train status: RUN - wait or timeout; FAIL/STOP - jump to NONREADY; SUCCESS - jump to INIT_DONE*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_port_rx_train_stat(lchip, (void*)(&psd), &train_stat));
    if(RX_TRAIN_RUN == train_stat) /*still running*/
    {
        if(PMA_RX_PRE_TRAIN3 <= fsm) /*timeout*/
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PRE_TRAIN: (lport %u, train_stat %u, fsm %u) disable PRE_TRAIN then go to PMA_RX_NONREADY\n", 
                lport, train_stat, fsm);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_8, (uint16)train_stat);
            CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
            /*optional PMA recovery*/
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        }
        else /*running*/
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PRE_TRAIN: (lport %u, train_stat %u, fsm %u) go to PMA_RX_PRE_TRAIN(n+1)\n", 
                lport, train_stat, fsm);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_9, (uint16)fsm);
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, fsm+1));
        }
    }
    else if((RX_TRAIN_FAIL == train_stat) || (RX_TRAIN_STOP == train_stat)) /*fail*/
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PRE_TRAIN: (lport %u, train_stat %u, fsm %u) disable PRE_TRAIN then go to PMA_RX_NONREADY\n", 
            lport, train_stat, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_10, 
            ((uint16)((fsm << 8) & 0xff00) | (uint16)(train_stat & 0x00ff)));
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
        /*optional PMA recovery*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
    }
    else /*success*/
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PRE_TRAIN: (lport %u, train_stat %u, fsm %u) disable PRE_TRAIN then go to PMA_RX_PCS_SYNC\n", 
            lport, train_stat, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_11, (uint16)train_stat);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_PCS_SYNC1));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_link_fsm_pcssync_proc(uint8 lchip, uint16 lport, uint32 fsm)
{
    uint32 link_mode = LINK_MODE_PCS_PMA;
    uint32 an_en     = 0;
    uint32 mac_en    = 0;
    uint16 dport     = 0;
    uint8  sig_vld   = 0;
    uint32 pcs_up    = 0;
    uint32 prbs_en   = 0;
    uint32 lpbk      = 0;
    sys_usw_dmps_serdes_id_t psd = {{0}};

    /*0. judge standalone mode and jump to PMA_RX_COVER*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode(lchip, lport, &link_mode));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_en(lchip, lport, &an_en));
    if((LINK_MODE_STDALONE == link_mode) || (1 == an_en))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PCS_SYNC: (lport %u, link_mode %u, an_en %u, fsm %u) go to PMA_RX_COVER\n", 
            lport, link_mode, an_en, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_12, 
            ((uint16)((link_mode << 8) & 0xff00) | (uint16)(an_en & 0x00ff)));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_COVER));
        return CTC_E_NONE;
    }

    /*1. judge if mac disable*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_mac_en(lchip, lport, &mac_en));
    if(!mac_en)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PCS_SYNC: (lport %u, mac_en %u) go to PMA_RX_NONREADY\n", 
            lport, mac_en);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_13, (uint16)mac_en);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        return CTC_E_NONE;
    }

    /*1.1 judge if prbs test enable, stay in current STATE*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_by_lport(lchip, lport, psd.serdes, &(psd.num)));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_prbs_rx_en(lchip, (void*)(&psd), &prbs_en));
    if(prbs_en)
    {
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_1, (uint16)prbs_en);
        return CTC_E_NONE;
    }

    /*1.2 judge if loopback enable, then if pcs_up jump to STATE POST_TRAIN, else wait 1 more period*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_pcs_link_status(lchip, dport, &pcs_up));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_loopback_mode(lchip, (void*)(&psd), &lpbk));
    if(DMPS_SERDES_LPBK_LOCAL == lpbk)
    {
        if(pcs_up)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PCS_SYNC: (lport %u, pcs_up %u, lpbk %u) go to PMA_RX_POST_TRAIN\n", 
                lport, pcs_up, lpbk);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_14, (uint16)lpbk);
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_POST_TRAIN1));
        }
        else
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PCS_SYNC: (lport %u, pcs_up %u, lpbk %u) waiting pcs up\n", 
                lport, pcs_up, lpbk);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_15, (uint16)lpbk);
        }
        return CTC_E_NONE;
    }

    /*2. judge signal valid*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_by_lport(lchip, lport, psd.serdes, &(psd.num)));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_signal_valid(lchip, (void*)(&psd), &sig_vld));
    if(RX_VALID_SIGNAL != sig_vld)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PCS_SYNC: (lport %u, sig_vld %u) go to PMA_RX_NONREADY\n", 
            lport, sig_vld);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_16, (uint16)sig_vld);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        /*optional PMA recovery*/
        return CTC_E_NONE;
    }

    /*3. judge pcs_up to start post train, or wait 1 more period, or restart pre-train*/
    if(pcs_up)
    {
        /*enable rx train*/
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PCS_SYNC: (lport %u, pcs_up %u, fsm %u) enable POST_TRAIN then go to PMA_RX_POST_TRAIN\n", 
            lport, pcs_up, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_17, (uint16)fsm);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), TRUE));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_POST_TRAIN1));
    }
    else
    {
        if(PMA_RX_PCS_SYNC1 == fsm) /*wait 1 more period*/
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PCS_SYNC: (lport %u, pcs_up %u, fsm %u) go to PCS_SYNC(n+1)\n", 
                lport, pcs_up, fsm);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_18, (uint16)fsm);
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, fsm+1));
        }
        else /*restart pre-train*/
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_PCS_SYNC: (lport %u, pcs_up %u, fsm %u) enable PRE_TRAIN then go to PMA_RX_PRE_TRAIN\n", 
                lport, pcs_up, fsm);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_41, (uint16)pcs_up);
            CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), TRUE));
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_PRE_TRAIN1));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_link_fsm_cl37_retrigger(uint8 lchip, uint16 lport, uint16 psd)
{
    uint32 cl37_en = 0;
    int32 ret = _sys_tmg_mac_get_cl37_en(lchip, lport, &cl37_en);

    SYS_CONDITION_RETURN((CTC_E_NONE != ret) || (0 == cl37_en), CTC_E_NONE);

#ifndef EMULATION_ENV
    CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, lport, 0));

    sal_udelay(1000);

    CTC_ERROR_RETURN(_sys_tmg_mac_set_port_serdes_tx_en(lchip, lport, 1));
#endif

    sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_42, psd);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_link_fsm_posttrain_proc(uint8 lchip, uint16 lport, uint32 fsm)
{
    uint32 link_mode  = LINK_MODE_PCS_PMA;
    uint32 an_en      = 0;
    uint32 mac_en     = 0;
    uint8  train_stat = 0;
    uint8  sig_vld    = 0;
    uint16 dport      = 0;
    uint32 prbs_en    = 0;
    uint32 lpbk       = 0;
    sys_usw_dmps_serdes_id_t psd = {{0}};

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_by_lport(lchip, lport, psd.serdes, &(psd.num)));
    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    /*0. judge standalone mode and jump to PMA_RX_COVER*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode(lchip, lport, &link_mode));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_en(lchip, lport, &an_en));
    if((LINK_MODE_STDALONE == link_mode) || (1 == an_en))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, 
            "[DAEMON] PMA_RX_POST_TRAIN: (lport %u, link_mode %u, an_en %u, fsm %u) disable POST_TRAIN then go to PMA_RX_COVER\n", lport, link_mode, an_en, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_19, 
            ((uint16)((link_mode << 8) & 0xff00) | (uint16)(an_en & 0x00ff)));
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_COVER));
        return CTC_E_NONE;
    }

    /*1. judge if mac disable*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_mac_en(lchip, lport, &mac_en));
    if(!mac_en)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_POST_TRAIN: (lport %u, mac_en %u) disable POST_TRAIN then go to PMA_RX_NONREADY\n", 
            lport, mac_en);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_20, (uint16)mac_en);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
        /*optional PMA recovery*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        return CTC_E_NONE;
    }

    /*1.1 judge if prbs test enable, stay in current STATE*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_prbs_rx_en(lchip, (void*)(&psd), &prbs_en));
    if(prbs_en)
    {
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_1, (uint16)prbs_en);
        return CTC_E_NONE;
    }

    /*1.2 judge if loopback enable, disable POST_TRAIN and jump to STATE RX_TRAIN_DONE*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_loopback_mode(lchip, (void*)(&psd), &lpbk));
    if(DMPS_SERDES_LPBK_LOCAL == lpbk)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_POST_TRAIN: (lport %u, lpbk %u, fsm %u) disable POST_TRAIN then go to RX_TRAIN_DONE\n", 
            lport, lpbk, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_21, (uint16)lpbk);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
        /*release all reset*/
        CTC_ERROR_RETURN(_sys_tmg_mac_set_rx_rst_condition(lchip, dport, RST_PCS_0_MAC_0));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_TRAIN_DONE));
        return CTC_E_NONE;
    }

    /*2. judge post train status: RUN - wait or timeout; FAIL/STOP - jump to NONREADY; SUCCESS - jump to READY*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_port_rx_train_stat(lchip, (void*)(&psd), &train_stat));
    if(RX_TRAIN_RUN == train_stat) /*still running*/
    {
        if(PMA_RX_POST_TRAIN3 <= fsm) /*timeout*/
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_POST_TRAIN: (lport %u, train_stat %u, fsm %u) disable POST_TRAIN then go to PMA_RX_NONREADY\n", 
                lport, train_stat, fsm);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_22, (uint16)fsm);
            CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
            /*optional PMA recovery*/
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        }
        else /*running*/
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_POST_TRAIN: (lport %u, train_stat %u, fsm %u) go to PMA_RX_POST_TRAIN(n+1)\n", 
                lport, train_stat, fsm);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_23, (uint16)fsm);
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, fsm+1));
        }
    }
    else if((RX_TRAIN_FAIL == train_stat) || (RX_TRAIN_STOP == train_stat)) /*fail*/
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_POST_TRAIN: (lport %u, train_stat %u, fsm %u) disable POST_TRAIN then go to PMA_RX_NONREADY\n", 
            lport, train_stat, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_24, (uint16)fsm);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
        /*optional PMA recovery*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
    }
    else /*success*/
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_get_signal_valid(lchip, (void*)(&psd), &sig_vld));
        if(RX_VALID_SIGNAL != sig_vld)
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_TRAIN_DONE: (lport %u, sig_vld %u) set RX rst to default then go to PMA_RX_NONREADY\n", 
                lport, sig_vld);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_28, (uint16)sig_vld);
            CTC_ERROR_RETURN(_sys_tmg_mac_set_rx_rst_condition(lchip, dport, RST_PCS_0_MAC_1));
            /*optional PMA recovery*/
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
            return CTC_E_NONE;
        }
        else
        {
            SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_POST_TRAIN: (lport %u, train_stat %u, fsm %u) disable POST_TRAIN, release all RX reset, then go to PMA_RX_TRAIN_DONE\n", 
                lport, train_stat, fsm);
            sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_25, (uint16)fsm);
            CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
            /*release all reset*/
            CTC_ERROR_RETURN(_sys_tmg_mac_set_rx_rst_condition(lchip, dport, RST_PCS_0_MAC_0));
            CTC_ERROR_RETURN(_sys_tmg_mac_link_fsm_cl37_retrigger(lchip, lport, psd.serdes[0]));
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_TRAIN_DONE));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_link_fsm_traindone_proc(uint8 lchip, uint16 lport)
{
    uint32 link_mode = LINK_MODE_PCS_PMA;
    uint32 an_en     = 0;
    uint32 mac_en    = 0;
    uint16 dport     = 0;
    uint8  sig_vld   = 0;
    uint32 pcs_up    = 0;
    uint32 prbs_en   = 0;
    uint32 lpbk      = 0;
    sys_usw_dmps_serdes_id_t psd = {{0}};

    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));

    /*0. judge standalone mode and jump to PMA_RX_COVER*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode(lchip, lport, &link_mode));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_en(lchip, lport, &an_en));
    if((LINK_MODE_STDALONE == link_mode) || (1 == an_en))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_TRAIN_DONE: (lport %u, link_mode %u, an_en %u) go to PMA_RX_COVER\n", 
            lport, link_mode, an_en);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_26, 
            ((uint16)((link_mode << 8) & 0xff00) | (uint16)(an_en & 0x00ff)));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_COVER));
        return CTC_E_NONE;
    }

    /*1. judge if mac disable*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_mac_en(lchip, lport, &mac_en));
    if(!mac_en)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_TRAIN_DONE: (lport %u, mac_en %u) go to PMA_RX_NONREADY\n", 
            lport, mac_en);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_27, (uint16)mac_en);
        /*optional PMA recovery*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        return CTC_E_NONE;
    }

    /*1.1 judge if prbs test enable, stay in current STATE*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_by_lport(lchip, lport, psd.serdes, &(psd.num)));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_prbs_rx_en(lchip, (void*)(&psd), &prbs_en));
    if(prbs_en)
    {
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_1, (uint16)prbs_en);
        return CTC_E_NONE;
    }
    /*1.2 judge if loopback enable, jump to RX_READY*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_loopback_mode(lchip, (void*)(&psd), &lpbk));
    if(DMPS_SERDES_LPBK_LOCAL == lpbk)
    {
        CTC_ERROR_RETURN(_sys_tmg_mac_get_pcs_link_status(lchip, dport, &pcs_up));
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_TRAIN_DONE: (lport %u, pcs_up %u) lpbk en go to PMA_RX_READY\n", 
            lport, pcs_up);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_40, (uint16)pcs_up);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_READY));
        return CTC_E_NONE;
    }

    /*2. judge signal valid */
    CTC_ERROR_RETURN(_sys_tmg_mac_get_signal_valid(lchip, (void*)(&psd), &sig_vld));
    if(RX_VALID_SIGNAL != sig_vld)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_TRAIN_DONE: (lport %u, sig_vld %u) set RX rst to default then go to PMA_RX_NONREADY\n", 
            lport, sig_vld);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_28, (uint16)sig_vld);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_rx_rst_condition(lchip, dport, RST_PCS_0_MAC_1));
        /*optional PMA recovery*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        return CTC_E_NONE;
    }

    /*3. jump to RX_READY FSM, no matter pcs up or down*/
    CTC_ERROR_RETURN(_sys_tmg_mac_get_pcs_link_status(lchip, dport, &pcs_up));
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_TRAIN_DONE: (lport %u, pcs_up %u) go to PMA_RX_READY\n", 
        lport, pcs_up);
    sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_29, (uint16)pcs_up);
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_READY));

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_link_fsm_rxready_proc(uint8 lchip, uint16 lport)
{
    uint32 link_mode  = LINK_MODE_PCS_PMA;
    uint32 an_en      = 0;
    uint32 mac_en     = 0;
    uint16 dport      = 0;
    uint32 mii_up     = 0;
    uint32 prbs_en    = 0;
    sys_usw_dmps_serdes_id_t psd = {{0}};

    /*0. judge standalone mode and jump to PMA_RX_COVER*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode(lchip, lport, &link_mode));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_en(lchip, lport, &an_en));
    if((LINK_MODE_STDALONE == link_mode) || (1 == an_en))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_READY: (lport %u, link_mode %u, an_en %u) go to PMA_RX_COVER\n", 
            lport, link_mode, an_en);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_30, 
            ((uint16)((link_mode << 8) & 0xff00) | (uint16)(an_en & 0x00ff)));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_COVER));
        return CTC_E_NONE;
    }

    /*1. judge if mac disable*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_mac_en(lchip, lport, &mac_en));
    if(!mac_en)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_READY: (lport %u, mac_en %u) go to PMA_RX_NONREADY\n", 
            lport, mac_en);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_31, (uint16)mac_en);
        /*optional PMA recovery*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        return CTC_E_NONE;
    }

    /*1.1 judge if prbs test enable, stay in current STATE*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_by_lport(lchip, lport, psd.serdes, &(psd.num)));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_prbs_rx_en(lchip, (void*)(&psd), &prbs_en));
    if(prbs_en)
    {
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_1, (uint16)prbs_en);
        return CTC_E_NONE;
    }

    /*2. judge MII status: up - do nothing; down - set mac-pcs as before, then go to NONREADY*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));
    CTC_ERROR_RETURN(_sys_tmg_mac_get_link_up(lchip, dport, FALSE, SYS_MAC_MII_LINK_RAW, &mii_up));
    if(!mii_up)
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_READY: (lport %u, mii_up %u) set RX rst to default then go to PMA_RX_NONREADY\n", 
            lport, mii_up);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_32, (uint16)mii_up);
        CTC_ERROR_RETURN(_sys_tmg_mac_set_rx_rst_condition(lchip, dport, RST_PCS_0_MAC_1));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_link_fsm_rxcover_proc(uint8 lchip, uint16 lport)
{
    uint32 link_mode  = LINK_MODE_PCS_PMA;
    uint32 an_en      = 0;

    /*0. judge standalone mode*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode(lchip, lport, &link_mode));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_en(lchip, lport, &an_en));
    if((LINK_MODE_STDALONE != link_mode) && (1 != an_en))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] PMA_RX_COVER: lport %u, link_mode %u, an_en %u\n", lport, link_mode, an_en);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_33, 
            ((uint16)((link_mode << 8) & 0xff00) | (uint16)(an_en & 0x00ff)));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
        return CTC_E_NONE;
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_link_fsm_exception_proc(uint8 lchip, uint16 lport, uint32 fsm)
{
    uint32 link_mode  = LINK_MODE_PCS_PMA;
    uint32 an_en      = 0;
    uint16 dport      = 0;
    sys_usw_dmps_serdes_id_t psd = {{0}};

    /*0. judge standalone mode and jump to PMA_RX_COVER*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_link_mode(lchip, lport, &link_mode));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_an_en(lchip, lport, &an_en));
    if((LINK_MODE_STDALONE == link_mode) || (1 == an_en))
    {
        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] exception: (lport %u, link_mode %u, an_en %u, fsm %u) go to PMA_RX_COVER\n", 
            lport, link_mode, an_en, fsm);
        sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_34, 
            ((uint16)((link_mode << 8) & 0xff00) | (uint16)(an_en & 0x00ff)));
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_COVER));
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_psd_by_lport(lchip, lport, psd.serdes, &(psd.num)));

    CTC_ERROR_RETURN(_sys_tmg_mac_set_port_rx_train_en(lchip, (void*)(&psd), FALSE));
    CTC_ERROR_RETURN(sys_usw_dmps_db_lport_2_dport(lchip, lport, &dport));
    CTC_ERROR_RETURN(_sys_tmg_mac_set_rx_rst_condition(lchip, dport, RST_PCS_0_MAC_1));
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_link_fsm(lchip, lport, PMA_RX_NONREADY));
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "[DAEMON] exception: (lport %u, fsm %u) disable RX TRAIN then go to PMA_RX_NONREADY\n", 
        lport, fsm);
    sys_usw_mac_link_log_record(lchip, lport, SYS_MAC_LOG_LINK_FSM_35, 1);

    return CTC_E_NONE;
}

int32
_sys_tmg_mac_daemon_thread(uint8 lchip, uint16 lport)
{
    uint32 fsm = PMA_RX_NONREADY;

    SYS_CONDITION_RETURN(CTC_E_NONE != sys_usw_dmps_db_get_link_fsm(lchip, lport, &fsm), CTC_E_NONE);
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "\n_sys_tmg_mac_daemon_thread: lport %u, fsm %u\n", lport, fsm);
    switch(fsm)
    {
        case PMA_RX_NONREADY   :
            CTC_ERROR_RETURN(_sys_tmg_mac_link_fsm_nonready_proc(lchip, lport));
            break;
        case PMA_RX_PRE_TRAIN1 :
        case PMA_RX_PRE_TRAIN2 :
        case PMA_RX_PRE_TRAIN3 :
            CTC_ERROR_RETURN(_sys_tmg_mac_link_fsm_pretrain_proc(lchip, lport, fsm));
            break;
        case PMA_RX_PCS_SYNC1  :
        case PMA_RX_PCS_SYNC2  :
            CTC_ERROR_RETURN(_sys_tmg_mac_link_fsm_pcssync_proc(lchip, lport, fsm));
            break;
        case PMA_RX_POST_TRAIN1:
        case PMA_RX_POST_TRAIN2:
        case PMA_RX_POST_TRAIN3:
            CTC_ERROR_RETURN(_sys_tmg_mac_link_fsm_posttrain_proc(lchip, lport, fsm));
            break;
        case PMA_RX_TRAIN_DONE :
            CTC_ERROR_RETURN(_sys_tmg_mac_link_fsm_traindone_proc(lchip, lport));
            break;
        case PMA_RX_READY      :
            CTC_ERROR_RETURN(_sys_tmg_mac_link_fsm_rxready_proc(lchip, lport));
            break;
        case PMA_RX_COVER      :
            CTC_ERROR_RETURN(_sys_tmg_mac_link_fsm_rxcover_proc(lchip, lport));
            break;
        default:
            CTC_ERROR_RETURN(_sys_tmg_mac_link_fsm_exception_proc(lchip, lport, fsm));
            break;
    }
    
    return CTC_E_NONE;
}

int32 _sys_tmg_mac_get_pcs_code_err(uint8 lchip, uint16 dport, uint32* p_value)
{
    sys_dmps_mac_api_db_t api_db;

    CTC_ERROR_RETURN(_sys_tmg_mac_fill_db_api(lchip, dport, FALSE, NULL, &api_db));
    DMPS_MAC_API(DMPS_MAC_MODULE_SHARED, DMPS_MAC_API_GET_CODE_ERR, lchip, &api_db, p_value);

    return CTC_E_NONE;
}

uint16 
_sys_tmg_mac_xpipe_map_lower_speed(uint8 lchip, uint16 src_speed)
{
    uint8 xpipe_alloc = 0;

    uint16 map_speed[3][SYS_PORT_SPEED_MAX] = {
    /*SYS_PORT_SPEED_1G  SYS_PORT_SPEED_100M  SYS_PORT_SPEED_10M  SYS_PORT_SPEED_2G5  SYS_PORT_SPEED_10G  SYS_PORT_SPEED_20G  SYS_PORT_SPEED_40G  SYS_PORT_SPEED_100G  SYS_PORT_SPEED_5G   SYS_PORT_SPEED_25G  SYS_PORT_SPEED_50G  SYS_PORT_SPEED_200G  SYS_PORT_SPEED_400G  SYS_PORT_SPEED_800G  SYS_PORT_SPEED_300G */
     {SYS_PORT_SPEED_1G, SYS_PORT_SPEED_100M, SYS_PORT_SPEED_10M, SYS_PORT_SPEED_2G5, SYS_PORT_SPEED_10G, SYS_PORT_SPEED_20G, SYS_PORT_SPEED_40G, SYS_PORT_SPEED_100G, SYS_PORT_SPEED_5G,  SYS_PORT_SPEED_25G, SYS_PORT_SPEED_50G, SYS_PORT_SPEED_200G, SYS_PORT_SPEED_400G, SYS_PORT_SPEED_800G, SYS_PORT_SPEED_300G},   
     {SYS_PORT_SPEED_1G, SYS_PORT_SPEED_100M, SYS_PORT_SPEED_10M, SYS_PORT_SPEED_2G5, SYS_PORT_SPEED_10G, SYS_PORT_SPEED_10G, SYS_PORT_SPEED_25G, SYS_PORT_SPEED_50G,  SYS_PORT_SPEED_5G,  SYS_PORT_SPEED_10G, SYS_PORT_SPEED_40G, SYS_PORT_SPEED_100G, SYS_PORT_SPEED_200G, SYS_PORT_SPEED_400G, SYS_PORT_SPEED_100G},
     {SYS_PORT_SPEED_1G, SYS_PORT_SPEED_100M, SYS_PORT_SPEED_10M, SYS_PORT_SPEED_2G5, SYS_PORT_SPEED_10G, SYS_PORT_SPEED_10G, SYS_PORT_SPEED_10G, SYS_PORT_SPEED_25G,  SYS_PORT_SPEED_5G,  SYS_PORT_SPEED_10G, SYS_PORT_SPEED_25G, SYS_PORT_SPEED_50G,  SYS_PORT_SPEED_100G, SYS_PORT_SPEED_200G, SYS_PORT_SPEED_100G},
    };

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_xpipe_alloc(lchip, &xpipe_alloc));

    return map_speed[xpipe_alloc][src_speed];
}

